How to fix BrowserRouter for React Apps on Apache

While learning React, most people develop and test their apps locally. I mean … they’re just demo apps for learning purposes right? Nobody wants to see stuff like that, so why even think of deploying the apps somewhere?

But then comes the day where you try to deploy a React App to a web server, so you could show it to the people out there: “Look! I made this!”. And that’s how it was for me too.

Deploying a static React bundle to an Apache web space

I already had a web space, so it was obvious for me to put it up there. Because I used create-react-app,ย  all I had to do was running npm run build and copy the contents of my app’s build folder to said web space.

YEAH! After all that hard work I just deployed my first React app!

I started clicking through several routes and everything seemed fine, until I refreshed the page or tried to access a route directly. I got a 404 error.

“But it works like a charm locally – why doesn’t it on my web space?”

Does that sound familiar to you?

Why is BrowserRouter not working?

Some research brought up several solutions. One of them:

“Use HashRouter instead of BrowserRouter”

Okay that would be an easy one. But since I wanted to have nice and clean URLs without the hash #, that was no option. So let’s dig deeper and have a look at the reason for the error.

When you’re visiting a route of your app directly, e.g. via https://myapp.com/route/123 Apache tries to map that URL to a file in the public folder. In this case it looks for /route/123.html which obviously doesn’t exist – therefore the 404 error.

To avoid that, we have to tell Apache to redirect all requests to our index.html so our app can perform some routing magic for that URL.

Fixing the app’s routing

Now here’s how to finally fix the routing. To tell Apache to redirect requests to index.html where our app lives, we have to modify the .htaccess file. If there is no such file in your app’s folder yet, just create it.

Then be sure that you put in those 4 lines that will magically make your routing work.

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]

After we put that .htaccess file into the same directory as the index.html, Apache will redirect each new request directly to your app.

Bonus: Deploying the React app to a sub directory

If you’re deploying your app into a sub directory, so it’s accessible e.g. viaย https://myapp.com/the-app, you’ll soon notice that there is another issue. Each click to a new route will transform the URL to something like https://myapp.com/route-abc – which will break again after a reload. But there is a simple fix for that:

BrowserRouter has a prop called basename where you can specify your sub-directory path:

<BrowserRouter basename="/the-app">

From now on, each Route like /contacts will result in an URL like http://myapp.com/the-app/contacts.

Wrapping up

Today you learned how to fix routing with BrowserRouter for React Apps deployed to Apache. You learned, why you even get the 404 error in the beginning, and that you can overcome that error by redirecting all requests back to index.html.

The next time you’re facing routing issues with a React App on Apache, head back to this article and try putting the redirect script to the .htaccess file.

Do you know more issues with hosting a static React app on Apache? Leave a comment at the bottom.

Improve your React Skills!

Learn about React concepts, helpful libraries or get tips & tricks for deploying your app and many more topics.

I semi regularly post about React. Don't miss out on my future posts! Sign up below to get them delivered directly into your inbox!

39 thoughts on “How to fix BrowserRouter for React Apps on Apache”

  1. After hitting about 10 other “solutions” elsewhere, yours is the one that really worked.
    Thanks for the tip Andreas!!

  2. Great, but is not working for me. I’m trying to deploy OHIF viewer, that is based on react, and my problem is the /viewer route never gets called. I’ve tried using the .htaccess file with de directives you posted, but I keep getting 404. Tried some other directives using VirtualHost and RewriteEngine and the same effect. Maybe you could guide me what can I do in this scenario. Thank you.

    1. Hmm… can you check if the RewriteModule in your Apache is activated? Seems like Apache is not redirecting your request to the index.html file.

  3. I’ve explored more than ten question in stackoverflow and the answer was here all the time. Thanks a lot man!

  4. Hi, thanks for sharing… I’m facing similar issue with tomcat (PSB https://stackoverflow.com/questions/58082196/getting-empty-screen-when-deploying-react-site-as-a-servlet-on-tomcat)

    And I noticed that tomcat don’t load the component of “/” route automatically when page is loaded, If I add links to these routes and press on them then components are loaded.

    Following this link: http://tuckey.org/urlrewrite/, tried implementing the RewriteUrl on tomcat 7, but it didn’t help!

    Out of ideas, any hints?

  5. I wanted to thank you dear.
    This saved me while I was struggling for almost 3 hours in midnight.
    Thqnk you and hope see your thoughts again ๐Ÿ™‚

  6. Hey Andreas,

    First thanks for the post, very helpful!!!

    I was wondering how can I make it work with nested routes like this:

    mydomain.com/projects/project1/
    mydomain.com/projects/project2/

    It works fine with this:
    mydomain.com/projects/
    mydomain.com/about/

    But it doesn’t works with the nested ones

    1. Hi Jordan!
      Sorry for the late reply – can you provide more information about the issue?
      Have a look at your browser console when you’re trying to access https://myapp.com/route/123/ and tell me what you can find there.
      It’s probably “just” a configuration issue.
      Cheers,
      Andreas

  7. Thank you for your valuable tips. Now I have been able to solve 404 issue by adding .htaccess file and working as a charm.

  8. Esta soluciรณn no me ayuda, al implementar los cambios me sigue mostrando una pantalla en blanco ๐Ÿ™

    1. This solution does not help me, when implementing the changes it still shows me a blank screen ๐Ÿ™

      1. Did you check the browser console? What does it say? Maybe there’s a hint what’s wrong.

  9. I laughed because this is exactly me: โ€œBut it works like a charm locally โ€“ why doesnโ€™t it on my web space?โ€

    I’m using a React front end and a WordPress installation in a subdirectory. The problem is that that requires an htaccess file already that clashes with entering the data above. This is what that one looks like:

    RewriteEngine On
    RewriteBase /
    RewriteRule ^index.php$ – [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]

    Which obviously has some repeats and conflicts with the suggested code.

    Would you have any idea how I would incorporate this? I know that it’s specific to WordPress but since this is so close to the issue I’m having I thought I’d give it a shot!

  10. [Hey Andreas,

    First thanks for the post, very helpful!!!

    I was wondering how can I make it work with nested routes like this:

    mydomain.com/projects/project1/
    mydomain.com/projects/project2/

    It works fine with this:
    mydomain.com/projects/
    mydomain.com/about/

    But it doesnโ€™t works with the nested ones]

    Hello Anreas! First Thank for useful tips!
    but i also struggle with same issue with Rodrigo.
    Do you also know how to handle this problem?

  11. Hi ! this solution help me to fix routes issue but because of my node server is not responding.
    P.S: it’s working completely fine without .htaccess file . my react app build is hosted in namecheap cpanel.

  12. Hey, before trying this I was able to render the Homepage but the others were blank pages. Now, after adding this .htaccess I’m getting this error:
    Internal Server Error
    The server encountered an internal error or misconfiguration and was unable to complete your request.

    Please contact the server administrator at to inform them of the time this error occurred, and the actions you performed just before this error.

    More information about this error may be available in the server error log.

    Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.

Leave a Reply

Your email address will not be published. Required fields are marked *