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?
Routing to the 404 PageYou specify the URL path and the element you want to render at that route. The 404 page displays for paths that don't exist on the website. So, instead of specifying the path, use an asterisk (*). Using * renders the NotFound component for all the URLs not specified in routes.
The concept of URL rewriting is simple. When a client sends a request to the Web server for a particular URL, the URL rewriting module analyzes the requested URL and changes it to a different URL on the same server.
Open Control Panel and then click on the "Programs and Features". Click on "Turn Windows features on or off". Select Internet Information Services and click on the OK button. To see whether or not IIS is enabled, press Windows + R key and type inetmgr and click on OK.
About the URL Rewrite module The Microsoft URL Rewrite Module 2.0 for IIS 7 and above enables IIS administrators to create powerful customized rules to map request URLs to friendly URLs that are easier for users to remember and easier for search engines to find.
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.
Download and install URL Rewrite on your server (development and production)
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>
<base/>
tag with a href
attribute to your app.<base href='/path/to/my/app'/>
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}>
....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With