Deploying a React Application to IIS: A Step-by-Step Guide

Hosting React applications on Windows servers using IIS is a common requirement in enterprise environments, especially when your organization already relies on Microsoft’s infrastructure. Unlike a Node.js server, IIS serves static files and does not natively support client-side routing, so you need to configure it properly to support your React SPA.

In this article, you’ll learn:

  • How to build and package your React app for production
  • How to set up a website (or application) in IIS
  • How to configure URL rewrite rules so that client-side routes resolve correctly
  • How to manage permissions, bindings, and other deployment details
  • Tips to troubleshoot common problems

Let’s get started.

Build Your React Application for Production

Before deploying, you need a production-ready build (static files) of your React app:

1. In your project root, ensure your package.json has the correct homepage field (especially if hosting under a subpath). For example:

{
  "name": "my-app",
  "version": "0.1.0",
  "homepage": "/app1",   // if your app will be under https://yourdomain.com/app1
  ...
}

Setting homepage helps generate correct paths in your build artifacts.

2. Run:

npm run build

This will produce a build folder containing the optimized, static files (HTML, JS, CSS, images, etc.).

3. Verify locally (for example, using a simple static server) to confirm that the build works before deploying to IIS.

Prepare the Server and Enable IIS Features

On the Windows server where you will host:

  • Ensure Internet Information Services (IIS) is installed (including static content support).
  • Install the URL Rewrite module in IIS (this is critical for handling SPA routes).
  • Make sure Windows firewall or network settings allow HTTP (and HTTPS) traffic to the port you intend to use (e.g. port 80 or 443).
  • Create (or choose) a folder where your build contents will reside, e.g. C:\inetpub\wwwroot\MyReactSite.

Create a Site or Application in IIS

1. Open IIS Manager (inetmgr).

2. Under the server node, right-click Sites → Add Website… (or optionally add an Application under an existing site).

  • Site name: choose a friendly name (e.g. MyReactApp)
  • Physical path: point this to the folder where you will copy the build files
  • Binding: set the host name, port, and optionally HTTPS certificate

3. Assign an Application Pool to the site. Use a pool with .NET v4.0 (or appropriate identity) and ensure it can run under the correct permissions.

4. Confirm that Default Document is configured: ensure index.html is among the default documents (so that visiting the root URL serves your React entry point).

Copy the Build Files to the Server

From your local machine (or a CI/CD pipeline), copy the entire contents of the build folder into the site’s physical path on the server (e.g. C:\inetpub\wwwroot\MyReactSite). Overwrite any existing content.

Make sure file permissions allow the IIS process (e.g. the Application Pool identity, or IUSR / IIS_IUSRS) to read these static files.

Add a web.config File for SPA Routing

React SPAs typically rely on client-side routing (e.g. React Router). If a user refreshes a route URL such as /about, IIS will try to find a folder or file named about and return 404. To avoid this, you need a rewrite rule so that all non-file, non-directory requests fall back to index.html.

Place a web.config in the root of your deployed React app (same folder as index.html). For example:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <!-- Static file handling rule -->
        <rule name="StaticAssets" stopProcessing="true">
          <match url="([\S]+[.](html|htm|js|css|png|gif|jpg|jpeg|svg|ico|json))" />
          <action type="Rewrite" url="{REQUEST_URI}" />
        </rule>

        <!-- React SPA fallback rule -->
        <rule name="ReactRoutes" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="/index.html" />
        </rule>
      </rules>
    </rewrite>

    <staticContent>
      <!-- Optionally add MIME types (e.g. for .json) if missing -->
      <remove fileExtension=".json" />
      <mimeMap fileExtension=".json" mimeType="application/json" />
    </staticContent>

  </system.webServer>
</configuration>

This web.config ensures:

  • Requests for actual static files (e.g. .js, .css, images) are served normally.
  • All other routes (that aren’t real files / directories) will be rewritten to index.html, letting your React app router handle them.

Test Access and Routing

  1. In IIS Manager, right-click your site → Manage Website → Browse.
  2. The homepage (/) should load your React application.
  3. Navigate to deep routes (e.g. /about, /dashboard) directly or by refreshing. Confirm the page renders correctly (no 404).
  4. Check your browser’s developer console and network tab for any failed resource loads.
  5. If you have APIs or backend under a subpath (e.g. /api), ensure your rewrite rules exclude those paths (so you don’t inadvertently rewrite API requests). You can add conditions to your rule (e.g. {REQUEST_URI} doesn’t start with /api) to prevent rewriting API calls.

Handling Applications Under Subpath

If your React app is deployed not at the root (e.g. /app1), you’ll need to:

  • Set the homepage field in package.json (e.g. "homepage": "/app1") so that assets reference the correct subpath
  • Adjust the web.config rules so fallback rewrites use the subpath base
  • Possibly update your React Router base path configuration

For example, in web.config, you may rewrite to /app1/index.html rather than /index.html.

Permissions, Logging, and SSL

  • Confirm that the Application Pool identity has read access to your build folder.
  • Enable Failed Request Tracing (FREB) or examine IIS logs (under %SystemDrive%\inetpub\logs\LogFiles) if routes don’t resolve.
  • If using HTTPS, configure a proper certificate binding in IIS, and optionally enforce HTTP → HTTPS redirection (via another rewrite rule).
  • Consider adjusting caching headers or compression settings in IIS for performance.

Common Pitfalls & Troubleshooting

  • Blank page / missing JS or CSS: likely your build references root paths (/static/js/...) but your app is under a subpath. Confirm homepage was set and rebuilt accordingly.
  • 404 on refresh: means the rewrite rule isn’t catching the route; maybe URL Rewrite module isn’t installed, or your web.config is malformed.
  • Rewrite loops: if your React router or backend also directs / paths, you might get redirect loops. Adjust conditions or paths to exclude API endpoints.
  • Permission denied: ensure the IIS process identity can access the content directory.
  • Mime types missing: if encountering “unknown MIME type” errors for JSON, fonts, etc., add those via <mimeMap> in web.config.
  • Binding conflicts: ensure your site’s binding (hostname, port) is not conflicting with other IIS sites.

Conclusion

Deploying a React application on IIS isn’t overly difficult, but requires careful setup of static file serving and URL rewriting so that your client-side routing functions properly. With a properly built React bundle, the right web.config fallback rules, correct permissions, and IIS bindings, your React SPA can run seamlessly under IIS.

Comments Add
No comments yet.