How To Properly Deploy a Static HTML Site (built by Next.JS) on IIS to Avoid 404's
Tags: nextjs, html, deployment, iis
Published: 2022-05-24 23:05:22

---
title: How To Properly Deploy a Static HTML Site (built by Next.JS) on IIS to Avoid 404's
published: true
description: In this how-to article, a simple solution is presented for deploying a next.js static website on IIS. So that you don't need to use node.js and server-side rendering.
tags: nextjs, html, deployment, iis
cover_image: https://upload.wikimedia.org/wikipedia/commons/thumb/5/52/Bundesstra%C3%9Fe_404_number.svg/640px-Bundesstra%C3%9Fe_404_number.svg.png
---

You can build your next.js project with the following command:

`npm run build`

Which in fact runs `next build && next export` (assuming build script is defined in package.json).

Now, you have the published files in the **out** folder. The build process creates an html file for each jsx or tsx file under pages folder. Also, it compiles all the scripts together as chunks, scss/css files, and also images under _next folder. You can find more information [here](https://nextjs.org/docs/deployment).

You copy all those files, put it into a folder on your web server, and create a website on IIS pointing that folder. It's done. Or I thought so.

The website worked well. I could navigate through the website by clicking the links.

But the problem was that when I copied a URL like www.xyz.com/products/abc (which points to products/abc.html) and paste it into the address bar of a newly opened browser tab and hit enter, I got a 404 page. IIS could not find it. As you imagine, this is a huge problem.

So, after digging a bit in the web, I came across a [S.O. post](https://stackoverflow.com/q/56779064/195124) which is about deployment on IIS but as a more general question. [One](https://stackoverflow.com/a/63098601/195124) of the answers includes the idea of using a web.config file including routing rules. Inspired with this answer and modifying the code a little bit for my needs, I created a web.config file as follows and put it into the website folder:

<code>
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
	<httpErrors errorMode="Custom" defaultResponseMode="File">
		<remove statusCode="404" />
		<error statusCode="404" path="/404.html" responseMode="ExecuteURL" />
   </httpErrors>
    <rewrite>
      <rules>
        <rule name="static assets" stopProcessing="true">
          <match url="([\S]+[.]((html?)|(svg)|(js)|(css)|(png)|(gif)|(jpe?g)|(json)))" />
        </rule>
        <rule name="reactRouter routes" 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="/{R:1}.html"/>
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>
</code>

So, basically what this web.config file does is to rewrite the URLs of requests except for the ones for html files and static files. For example /products/abc gets rewritten as /producs/abc.html. By doing so, the problem was solved. 

You will also notice the httpErrors section on top of the configuration code. This is to show a custom 404 page to the user if s/he requests a page that does not exist. [1]

Hopefully, this helps someone and earns him/her some precious time.

*[1]: Edit (2022-06-21): httpErrors section was added to the sample configuration code to show a custom 404 page.*