React & nginx routing to subdirectory
I was struggling with the same problem. Finally I was able to solve it using official documentation and a combination of answers:
Assumptions:
- Your React App is based on
create-react-app
package (you are usingreact-router-dom
). - You are using Nginx and the root path is being used by another service (or even another React/Gatsby App which is my case).
- You want to deploy the React App on a subdirectory and be able to serve all statics of your React App from that subdirectory.
React App Changes:
Based on official documentation.
- Update your
BrowserRouter
by adding abasename
. Example:<BrowserRouter history={history} basename="/webapp">
. - Specify a
homepage
on yourpackage.json
. Example:"homepage": "/webapp"
. - If you are referencing a static file by it's relative path, you should add the subdirectory to that reference. Example:
src="/static/logo/logo.png"
becomessrc="/webapp/static/logo/logo.png"
.
Nginx Changes:
location ^~ /webapp { alias /var/www/myapp/build; try_files $uri $uri/ /webapp/index.html;}
Here is an example of nginx location configuration:
location ^~ /analytics { alias /var/www/myapp/build; subs_filter href="/ href="http://foo.example.com/analytics; subs_filter src="/ src="http://foo.example.com/analytics;}
- The
location
is set to^~ /analytics
, meaning that the rules created in the location braces will become effective when somebody visits http://foo.example.com/analytics - The
alias
is set to the static build folder of create-react-app site/var/www/myapp/build
. That’ll be served when the visitor hits your subdirectory url foo.example.com/analytics - Next, the two
subs_filter
lines replace any reference tohref
andsrc
urls that start with the React app’s home directory/
with the new complete URL. That will ensure all your CSS and JS files are located and served correctly by NGINX.
The final thing, in the case of Create-React-App is that any references to createBrowserHistory
in your react router need to be replaced by createHashHistory
, as Browser History won’t work with the above NGINX configuration.
My website is called derekdawsonspersonalwebsite.com and I wanted to serve a react app I made at derekdawsonspersonalwebsite.com/metronome/
I got this working by doing the following:
- Added
"homepage": "/metronome",
to thepackage.json
file - If you are using react router, add
<BrowserRouter basename="/your_subdirectory">
, in my case:
<BrowserRouter basename="/metronome"> <div> <nav> <Link to="/"></Link> </nav> <Switch> <Route exact path="/" component={Metronome} /> </Switch> </div></BrowserRouter>
yarn run build
- I uploaded the contents of the build directory to this location on my server
/var/www/personalwebsite.com/metronome
- This is what my server block
/etc/nginx/sites-available/personalwebsite.com
looks like
server { listen 443 ssl; server_name derekdawsonspersonalwebsite.com www.derekdawsonspersonalwebsite.com; ssl_certificate /home/derek/ssl/derekdawsonspersonalwebsite.com_chain.crt; ssl_certificate_key /home/derek/ssl/derekdawsonspersonalwebsite.com_tld.key; location / { root /var/www/personalwebsite.com; index index.html; } location /metronome { root /var/www/personalwebsite.com; index index.html; }}server { listen 80 default_server; server_name derekdawsonspersonalwebsite.com www.derekdawsonspersonalwebsite.com; return 301 https://$host$request_uri;}