Easier way to run SSR websites (Node.js) on Windows IIS
Tags: iis, node, webdev
Published: 2024-03-09 14:20:50

_Sometimes you have no choice, but to use less-than-ideal tech stack the team familiar with, or perhaps the only tech stack the team knows._

## It begins as...

Here, I have a website. While it is a simple website, but does require server-side rendering (SSR) functionality. It may not pose an issue to any _modern_ web developer, but it becomes one when handing off to old-school Windows engineer.

Before it sounds like a complaint, it's worth noting that modern tech stacks and practices are generally cross-platform. There's no reason why I can't run my website under Windows IIS, regardless of how cumbersome it might be to hook up with the JavaScript runtime.

After conducting research and experimenting with [FastCGI](https://learn.microsoft.com/en-us/iis/configuration/system.webserver/fastcgi/) and [URL Rewrite](https://www.iis.net/downloads/microsoft/url-rewrite), I discovered another convenient module that seems to be under-discussed.

I'm not an expert in Windows IIS, so I can't speak to the differences under the hood, but from my experience, I find that **[httpPlatformHandler](https://learn.microsoft.com/en-us/iis/extensions/httpplatformhandler/httpplatformhandler-configuration-reference) is easier to setup**.

---

Before I share the walkthrough of IIS setup, we'll need the website running properly under JavaScript runtime (Node.js in this case).

---

## Setup httpPlatformHandler

1. Download and install [httpPlatformHandler](https://www.iis.net/downloads/microsoft/httpplatformhandler) from Microsoft.

1. Open the site under IIS, and navigate to: Handler Mapping > Add Module Mapping...

1. Enter the follow:

    | Key          | Value               |
    | ------------ | ------------------- |
    | Request path | *                   |
    | Module       | httpPlatformHandler |

1. Uncheck the "Request Restrictions..."

1. Navigate to: Configuration Editor > system.webService/httpPlatform

1. Enter the follow:

    | Key             | Value                            |
    | --------------- | -------------------------------- |
    | arguments       | .\\.output\server\index.mjs       |
    | processPath     | C:\Program Files\nodejs\node.exe |
    | starupTimeLimit | 20                               |

1. Under the environmentVariables, enter the following:

    | Key      | Value                |
    | -------- | -------------------- |
    | PORT     | %HTTP_PLATFORM_PORT% |
    | NODE_ENV | Production           |

---

🎉 Let's it. As of my understanding, all http request will now be handled by Node instead.

---

The final `web.config` should looks like this:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <handlers>
            <add 
                name="httpPlatformHandler" 
                path="*" 
                verb="*" 
                modules="httpPlatformHandler" 
                resourceType="Unspecified" 
                requireAccess="Script" 
            />
        </handlers>
        <httpPlatform 
            processPath="C:\Program Files\nodejs\node.exe" 
            arguments=".\.output\server\index.mjs" 
            startupTimeLimit="20" 
            stdoutLogEnabled="true" 
            stdoutLogFile=".\node.log"
        >
            <environmentVariables>
                <environmentVariable 
                    name="PORT" 
                    value="%HTTP_PLATFORM_PORT%" 
                />
                <environmentVariable 
                    name="NODE_ENV" 
                    value="Production" 
                />
            </environmentVariables>
        </httpPlatform>
    </system.webServer>
</configuration>
```

{% details Complains %}
The project would progress much more smoothly if the _old-school_ engineers provided insightful assistance, given that it falls within their area of expertise. However, they seem to push away responsibility instead of offering support. My intuition tells me that they may not even have a deep understanding of how IIS works under the hood, as they are accustomed to simply clicking buttons on the screen.
{% enddetails %}