Fixing the “cannot GET /URL” error on refresh with React Router and Reach Router (Tested On Apache and IIS)

Spread the love

We expect that on reload the single page apps such as React apps go to the URL that is in the browser but instead a 404 error occurs. Because the browser requests server in case of refresh but in case your app is loaded your app just changes the URL but does not reload the page and all requests are handled by the app and page is updated.

e.g. You have requested : http://xyz.com/abc

Then browser will send the request to server and server will try to find the file or directory named ‘abc’ (ofcourse the directory should have something to return which matches server rules). If it finds it then it will return it otherwise sends a 404 error.

And in case of React apps the JS captures the event and processes it. So no direct request to server for ‘abc’ file.

So, how can we make the app load correctly on every page refresh. We can configure our server in such a way that if the requested file or directory is not found then it will always redirect to home page i.e. ‘/’.

So, in Apache we can make an .htaccess file in the root of our website files and put the following in that file:

RewriteEngine On
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . / [L]

Don’t forget to reload the Apache in order to changes to take effect.

Use the following command to reload on CentOS:

systemctl reload httpd.service

For IIS you can use the following XML code. You can put that in a web.config in the root of your wwwroot folder

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Redirection" 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="/" appendQueryString="false" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>