15

React-Router enables your ReactJS app to become a SPA through simple routing components. When deploying to IIS, everything works fine when setup using bashHistory. However, when I try to use browserHistory, IIS is trying to return a directory instead of allowing React-Router to grab and resolve the route. How do I setup React-Router to work in an IIS environment?

jOshT
  • 1,525
  • 1
  • 11
  • 15

2 Answers2

37

The key to getting React-Router to work with IIS is to setup URL Rewrite rules. After looking at how some others have setup AngularJS SPA apps with IIS, I have come up with the following solution.

  1. Download and install URL Rewrite on your server (development and production)

  2. Setup rule to catch any url routes that ARE NOT files and ARE NOT directories. Optionally, you can negate any actual directories that you want serve regularly. More info can be found here on Microsoft's Documentation

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <system.webServer>
      <rewrite>
        <rules>
          <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" />
              <add input="{REQUEST_URI}" pattern="^/(docs)" negate="true" />
            </conditions>
            <action type="Rewrite" url="index.html" />
          </rule>
        </rules>
      </rewrite>
    </system.webServer>
    </configuration>
  1. In your base html page (index.html) add a <base/> tag with a href attribute to your app.

<base href='/path/to/my/app'/>

Yatrix
  • 13,361
  • 16
  • 48
  • 78
jOshT
  • 1,525
  • 1
  • 11
  • 15
  • 6
    Thanks alot. Not to many React'ers out there on IIS. This was pretty helpful. Up voted! – Puerto Jul 06 '17 at 20:27
  • 1
    Glad you found it helpful! IIS not my first choice, but necessity is the root of all invention :) – jOshT Jul 07 '17 at 05:43
  • Did you see any errors like this related to your react router when you implemented this chang?? "Warning: Automatically setting basename using is deprecated and will be removed in the next major release. The semantics of are subtly different from basename. Please pass the basename explicitly in the options to createHistory" – Puerto Jul 10 '17 at 17:09
  • 2
    An important point: create a file called "web.config" in your react folder that contains index.html, and paste the above xml as a starting point. – Brain2000 Dec 19 '19 at 16:26
  • Amazing! A SO answer that I could just copy and paste and it works! Note @Brain2000 comment, that's what I actually did rather than trying to configure it in IIS. – Morvael Apr 30 '20 at 08:54
  • Is there a simple way to do this without the rewrite module? – user2966445 Aug 16 '21 at 05:02
  • super easy and awesome solution for the IIS folks here :) Thanks so much! – jAC Nov 14 '21 at 18:28
3

Just building on this answer for anyone interested. If your like me and need to deploy your app via script. Here are the powershell scripts necessary to create the webconfiguration above.

This installs the URL Rewrite on the server.

    #Install IIS UrlRewrite
    If(Test-Path c:/msi) {
    Invoke-WebRequest 'http://download.microsoft.com/download/C/F/F/CFF3A0B8-99D4-41A2-AE1A-496C08BEB904/WebPlatformInstaller_amd64_en-US.msi' -OutFile c:/msi/WebPlatformInstaller_amd64_en-US.msi
    Start-Process 'c:/msi/WebPlatformInstaller_amd64_en-US.msi' '/qn' -PassThru | Wait-Process
    cd 'C:/Program Files/Microsoft/Web Platform Installer'; .\WebpiCmd.exe /Install /Products:'UrlRewrite2,ARRv3_0' /AcceptEULA /Log:c:/msi/WebpiCmd.log
    }
    else {
    New-Item c:/msi -ItemType Directory
    Invoke-WebRequest 'http://download.microsoft.com/download/C/F/F/CFF3A0B8-99D4-41A2-AE1A-496C08BEB904/WebPlatformInstaller_amd64_en-US.msi' -OutFile c:/msi/WebPlatformInstaller_amd64_en-US.msi
    Start-Process 'c:/msi/WebPlatformInstaller_amd64_en-US.msi' '/qn' -PassThru | Wait-Process
    cd 'C:/Program Files/Microsoft/Web Platform Installer'; .\WebpiCmd.exe /Install /Products:'UrlRewrite2,ARRv3_0' /AcceptEULA /Log:c:/msi/WebpiCmd.log
    }

And here is how you add the rules.

Add-WebConfigurationProperty -pspath "$IISPath\MyWebsite" -filter "system.webServer/rewrite/rules" -name "." -value @{name='Home';stopProcessing='True'}
Set-WebConfigurationProperty -pspath "$IISPath\MyWebsite"  -filter "system.webServer/rewrite/rules/rule/match" -name "url" -value ".*"

Add-WebConfiguration -pspath "$IISPath\MyWebsite" -filter "system.webServer/rewrite/rules/rule[@name='Home']/conditions" -value @{ input="{REQUEST_FILENAME}"; matchType="IsFile"; negate="true" }
Add-WebConfiguration -pspath "$IISPath\MyWebsite" -filter "system.webServer/rewrite/rules/rule[@name='Home']/conditions" -value @{ input="{REQUEST_FILENAME}"; matchType="IsDirectory"; negate="true" }
Add-WebConfiguration -pspath "$IISPath\MyWebsite" -filter "system.webServer/rewrite/rules/rule[@name='Home']/conditions" -value @{ input="{REQUEST_URI}"; pattern="^/(docs)"; negate="true" }

Set-WebConfigurationProperty -pspath "$IISPath\MyWebsite"  -filter "system.webServer/rewrite/rules/rule/action" -name "type" -value "Rewrite" 
Set-WebConfigurationProperty -pspath "$IISPath\MyWebsite"  -filter "system.webServer/rewrite/rules/rule/action" -name "url" -value "index.html"

These scripts can be executed locally or remotely via Invoke-Command in Powershell.

Also I had some trouble with React Router warnings and with using the base tag in my header on index.html. This link is fairly helpful.

https://github.com/ReactTraining/react-router/issues/4006

I essentially change my React-Router package and History package to version 3.x and set the config in my router to get rid of the deprecation warnings. This is my react router now.

import { useRouterHistory } from 'react-router'
import { createHistory } from 'history'

const history = useRouterHistory(createHistory)({
basename: '/base-path'
})

ReactDOM.render(
  <Router history={history}>
 ....
Puerto
  • 1,072
  • 3
  • 11
  • 32