Search code examples
reactjsazurereact-routeriisnode

React Router in Azure IIS Rewrite


I have a few routes in my React app that accept a GUID value as a parameter. For instance, a user receives an email with a link and follows that link to verify and activate their account on the site.

<Route exact path="/register" component={Register} />
<Route path="/register/:id" component={RegistrationConfirmation} />

When I deploy this app to Azure, I am able to serve the page through express and navigate to http://[mysiteUrl]/register but static links provided in confirmation emails yield 404 errors.

Here is my current web.config from the site/wwwroot folder:

 <rules>
     <rule name="Rewrite Text Requests" stopProcessing="true">
         <match url=".*" />
             <conditions>
                        <add input="{HTTP_METHOD}" pattern="^GET$" />
                        <add input="{HTTP_ACCEPT}" pattern="^text/html" />
                        <add input="{REQUEST_URI}" pattern="^api/" negate="true" />
             </conditions>
             <action type="Rewrite" url="dist/index.html" />
     </rule>
     <rule name="register" stopProcessing="true">
         <match url="^/register/*" />
         <action type="Rewrite" url="dist/index.html" appendQueryString="true" />
     </rule>
 </rules>

This doesn't work and looks like it just attempts to navigate to a separate page in the same location: routeError

What is the correct way to configure this file so that I can serve up parameterized routes?


Solution

  • Alright, so the issue was pretty stupid, but I did manage to get it sorted. The issue was the route resolution in the index.html

    This:

    <script type="text/javascript" src="./dist/bundle.js"></script>
    

    Had to be changed to this:

    <script type="text/javascript" src="/dist/bundle.js"></script>
    

    Here's my final web.config:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <system.webServer>
        <webSocket enabled="false" />
        <handlers>
          <add name="iisnode" path="./app.js" verb="*" modules="iisnode"/>
        </handlers>
        <rewrite>
            <rules>
         <rule name="React Requests">
             <match url="/*" />
             <conditions>
                <add input="{HTTP_METHOD}" pattern="^GET$" />
                <add input="{HTTP_ACCEPT}" pattern="^text/html" />
             </conditions>
             <action type="Rewrite" url="./dist/index.html" />
         </rule>
         </rules>
        </rewrite>
    
        <security>
          <requestFiltering>
            <hiddenSegments>
              <add segment="node_modules" />
            </hiddenSegments>
          </requestFiltering>
        </security>
    
        <!-- Make sure error responses are left untouched -->
        <httpErrors existingResponse="PassThrough" />
    
      </system.webServer>
    </configuration>
    

    Should be noted that I'm not leaving anything up to Express. All the routing is handled here.