meds
meds

Reputation: 22966

Azure App service not working with custom routing in React-Redux web app - need wildcard virtual directories?

I have custom routes like follows:

// @flow

import React, { PureComponent } from 'react';
import { Switch, Redirect } from 'react-router-dom';
import { withRouter } from 'react-router';

import { Route } from 'components/Routes';
import Story from 'pages/Story';
import Page404 from 'pages/404';

class Routes extends PureComponent<{}> {
  render() {
    return (
      <Switch>
        <Route exact path="/" render={props => <Story {...props} />} />
        <Route
          exact
          path="/chapter/:id"
          render={props => <Story {...props} />}
        />
        <Route path="/404" render={props => <Page404 {...props} />} />
        <Redirect to="/404" /* Must be the last one */ />
      </Switch>
    );
  }
}

export default withRouter(Routes);

This works fine in localhost, if I visit localhost:3000/chapter/3 the web app redirects successfully, unfortunately in live builds running on azure app services if I visit: mysite.azurewebsites.net/chapter/3 I'm given an error:

The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

I'm running a Windows based App Service plan. I'm sure there's some option to set up redirecting, i.e. /chapter/* -> /www_siteroot/ but I haven't been able to figure out how to do it.

I fixed the issue by going to the app service settings and adding /chapter/1, /chapter/2, etc, etc under 'Virtual applications and directories' and directing them to site\wwwroot.

I'd prefer to have a wildcard option like /chapter/* but it doesn't seem to work and I get an error.

Upvotes: 9

Views: 11295

Answers (4)

Mike Skott
Mike Skott

Reputation: 301

I was trying to do the same with a Azure Static Web App using a Create React App that deploys from GitHub. None of the above seemed to work for me, but adding a staticwebapp.config.json in my project's root with the following got URL rewriting working properly again:

{
  "navigationFallback": {
    "rewrite": "index.html",
    "exclude": ["*.{svg,png,jpg,gif}","*.{css,scss}","*.js"]
  }
}

See the documentation about Fallback Routes here.

Upvotes: 0

Tommi L.
Tommi L.

Reputation: 434

Solution to those who are running App Service with Linux is to create configuration file .htaccess instead of web.config. Create this file to root of your public folder with the following content:

RewriteEngine On
RewriteRule "^[^\.]+$" "index.html"

Upvotes: 1

ericswyang
ericswyang

Reputation: 161

If you have your repo connected to the Azure Web App, then you can place this web.config file in the /public folder of a create-react-app project.

<?xml version="1.0"?>
<configuration>
    <system.webServer>

        <directoryBrowse enabled="false"/>

        <urlCompression doDynamicCompression="true" doStaticCompression="true"/>

        <!-- <staticContent>
            <clientCache cacheControlMaxAge="120.00:00:00" cacheControlMode="UseMaxAge"/>
        </staticContent> -->
        <caching enabled="true" enableKernelCache="true">
            <profiles>
                <add extension=".css" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange"/>
                <add extension=".js" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange"/>
                <add extension=".svg" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange"/>
                <add extension=".png" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange"/>
            </profiles>
        </caching>

        <rewrite>
            <rules>
                <rule name="React 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="^/(api)" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="/index.html" />
                </rule>
            </rules>
        </rewrite>

    </system.webServer>
</configuration>

Upvotes: 16

Mike Urnun MSFT
Mike Urnun MSFT

Reputation: 478

Since you're on Windows based App Service Plan, your Azure webapp is running under IIS with URL Rewriting module enabled. As such, you can create a simple URL Rewrite rule that directs all requests coming from https://mysite.azurewebsites.net/chapter/* to your site root in which case the client will receive your React/Redux application, and your React application would take care of all subsequent logic and rendering of content etc..

Here are the steps to create this URL Rewrite rule:

  1. In Azure Portal, create FTP deployment credentials.
  2. Locally on your computer, create a Web.config file with following content:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Chapter-Redirect" stopProcessing="true">
                    <match url="chapter/*" />
                    <action type="Rewrite" url="/" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>
  1. Open up FTP client (Filezilla is a good one) and login to your site and upload the Web.config file.
  2. Test by visiting: https://mysite.azurewebsites.net/chapter/*

Here's more info on IIS URL Rewrite.

Upvotes: 6

Related Questions