Jump to content

Deploying React (Router) app to the subfolder on server

Posted in React · 3 minutes read

  • May 2018 - Updated to match React Router v4 API.
  • September 2019 - Updated to match React Router v5 API, added React Create App part.

If you ever had to deploy React Router app to the subfolder on the server, you know what the problem is. Routes will get messed up once you upload it to the server. Here are two solutions I use in these cases.

Easy way, just use HashRouter #

The easiest way to achieve this is to use HashRouter instead of BrowserRouter.

import { HashRouter, Route } from 'react-router-dom';

// Then in render
<HashRouter>
  <Route path='/' component={ Home } exact />
  <Route path='/about' component={ About } exact />
  {/*...*/}
</HashRouter>

This is the best approach if your subfolder name changes (for example, if folder name is a build version). But you'll have /#/ included in the every URL. If this bothers you, check the second solution.

Example of the routes

  • http://yourserver.com/path/to/subfolder/
  • http://yourserver.com/path/to/subfolder/#/about
  • http://yourserver.com/path/to/subfolder/#/search

Hard way, setting base path by hand #

If you want to keep browser history implementation, you'll need to change few things. First, we need to update our routes to include full absolute path to the subfolder.

Using React Router's basename #

As Davis Cabral pointed out in the comments, instead of manually adding publicPath to all routes, it can be achieved by using React Router's basename prop.

import { BrowserRouter, Route } from 'react-router-dom';

// Then in render
<BrowserRouter basename='/path/to/subfolder/'>
  <Route path='/' component={ Home } exact />
  <Route path='/about' component={ About } exact />
  {/*...*/}
</BrowserRouter>

Doing it by the hand #

I define my routes something like this:

const publicPath = '/path/to/subfolder/';

export const routeCodes = {
  HOME: publicPath,
  SEARCH: `${ publicPath }search`,
  ABOUT: `${ publicPath }about`,
};

// Then you can use them like this
// <Route exact path={ routeCodes.ABOUT } component={ About } />

Setting up .htaccess file #

Once uplodaded to the server any route (but root /) will return 404 error. For example, if you try to open http://yourserver.com/path/to/subfolder/about, server will look for file (or folder) named about in the app subfolder. As it doesn't exist, it will fail with 404.

You'll need to add a simple .htaccess file, in order to tell the server to fallback to our index.html file. This is the same configuration we would use if the application was on the server root, just with a different absolute path to our index file.

RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]

# Fallback all other routes to index.html
RewriteRule ^ /path/to/subfolder/index.html [L]

Now our example routes will look like this

  • http://yourserver.com/path/to/subfolder/
  • http://yourserver.com/path/to/subfolder/about
  • http://yourserver.com/path/to/subfolder/search

Notice about webpack's output -> publicPath configuration #

If you are using publicPath in webpack's output object, make sure you either remove it or update to match your server build path. Removing it is easier, as it will create relative links, which should work with your new configuration.

output: {
  publicPath: '/', // Remove, or update it
  path: './build',
  filename: 'app-[hash].js',
},

Create React App #

A lot of people are using Create React App. To deploy it in subfolder, you can set homepage in your package.json, for more details check their documentation


I'm also interested if anyone has different/better ideas, cheers!

Comments (29)

13. May 2020
Andrei

Thank you! Very helpful!

3. April 2020
greatghoul

Great, you saved my life!

13. February 2020
Judy

Great article. This solves my bookmark URL issue without adding a web.config file.

17. December 2019
Ali Lishan

GREAT!!!!! I cannot thank you enough ... i have been searching high and low. And you updated the post ! .. You my man .. are a Legend!

16. December 2019
Stanko

Hi Catarina,

I guess you haven't used hash routing. That means you still need to setup proper server redirections. If you are using appache, you should check Setting up .htaccess file section in this post.

Cheers!

16. December 2019
Catarina

Hi! It helps me in some things but I still can't use routes. I got error 404. I'm using create-react-app and the project is hosted on iis Someone can help?

10. September 2019
Stanko

That is correct Dave, I just updated the post.

Cheers!

10. September 2019
Dave

Maybe this changed in a newer version of ReactRouter? I get: Failed to compile ./src/App.js Line 45: 'hashHistory' is not defined no-undef

13. June 2019
Amar

How to deal this concept with Create React App? As, I have doubt regarding setting Public path in webpack.

5. April 2019
Shubham Kesarwani

In my case there are two projects in two different subdirectories. and based on request i want to redirect to that particular project.

For e.g. www.test.com/us should go to project residing in 'us' directory and same should happen with www.test.com/in

RewriteRule ^ /path/to/subfolder/index.html [L] How can I get subfolder dynamically from url.

Please help

27. March 2019
Charlie

@Robert

Thanks for you comment man! I've been searching around how to work the build react app on IIS. Im using connected react router and i set my homepage from what you've said there, setting the basename for history

history = createBrowserHistory({basename: ${process.env.PUBLIC_URL} })

and voila! when the page refreshed, the 404 error page was gone. Thanks again!

18. March 2019
Robert

Hi, thanks for the write up, I just wanted to add that you can use

<Router basename={ process.env.PUBLIC_URL }>

then add

"homepage": "your url plus sub-directory"

to "package.json", and you should be good to go

5. March 2019
Stanko

Hello Keyra,

I can't think of a way to do it dynamically in a library, without using hash routing. If you figure out a way, please share the solution.

Cheers!

5. March 2019
Keyra

Thanks for this useful post! I have a question, what if I don't want to have # in my URLs, but I don't know the path on coding / compilation time? I need to have a package, that then can be deployed at any server (root, subfolder, whatever)

22. January 2019
Salitha

This works fine! You saved my day.. Thanx a lot :D

28. September 2018
Tin Htun

Thanks a lot! You save my day.

6. September 2018
Eugene

Thanks Stanko, you're a legend!

Was looking for a solution for the past couple of hours and this worked like magic.

9. July 2018
Stanko

Hello Ram,

That won't work as location.pathname is dynamic property. For example it will be / on your home page, but something like /users/view/1 on user profile. Then all of your links would be relative to /users/view/1 instead of /.

Cheers!

7. July 2018
Ram

@Stanko:

Instead of this snippet, <BrowserRouter basename='/path/to/subfolder/'>

can't we use this one ?

<BrowserRouter basename={location.pathname}>

This make the path configurable and this will work even if the path of subfolder changes, what do you feel about this?

11. May 2018
TheKid_||_

@Davis is the best solutions ;D

12. April 2018
Stanko

Hey @Mikkel, .htaccess should be at the root of your project (where your index.html is).

@Davis, that is pretty neat, I missed that prop, thanks!

12. April 2018
Mikkel

Where are you storing the .htaccess file?

23. March 2018
Davis Cabral

You can use the Router prop basename for this.

<Router basename={ '/subdir' } history={ history }> </Router>

6. March 2018
Stanko

As I mentioned in the article already, the biggest drawback is that you'll have /#/ in your URLs.

6. March 2018
Biswajit

I solved this problem by using HashRouthing instead of BrowserRouting. Just I want to know what will be the wrong of using it.

2. March 2018
Stanko

Hello @Biswajit,

Unfortunately, I can't help you with that as I have no experience with IIS, but a quick search provided me with Translate .htaccess Content to IIS web.config. Hopefully that will help you.

Cheers!

2. March 2018
Biswajit

Can you please tell me how I will add .htaccess file, if I am deploying into IIS server.My app is in sub folder.

I donot have access to iis server. I will do deploy using jenkins.

I will appreciate your help.

20. February 2018
Wilfried

Thank you, helped me to solve my routing problem on sub folders.

24. November 2017
And

Thanks!