90

I uploaded react.js application to a server. I'm using nginx server. Application is working fine. But when I go to another page & refresh, the site is not working. It's showing a 404 Not found error.

How can I solve this?

Art
  • 2,836
  • 4
  • 17
  • 34
Sunil tc
  • 2,482
  • 4
  • 19
  • 46

9 Answers9

240

When your react.js app loads, the routes are handled on the frontend by the react-router. Say for example you are at http://a.com. Then on the page you navigate to http://a.com/b. This route change is handled in the browser itself. Now when you refresh or open the url http://a.com/b in the a new tab, the request goes to your nginx where the particular route does not exist and hence you get 404.

To avoid this, you need to load the root file(usually index.html) for all non matching routes so that nginx sends the file and the route is then handled by your react app on the browser. To do this you have to make the below change in your nginx.conf or sites-enabled appropiately

location / {
 try_files $uri /index.html;
}

This tells nginx to look for the specified $uri, if it cannot find one then it send index.html back to the browser. (See https://serverfault.com/questions/329592/how-does-try-files-work for more details)

Michael Freidgeim
  • 26,542
  • 16
  • 152
  • 170
Panther
  • 8,938
  • 3
  • 23
  • 34
  • 3
    Is there a way to pass to my react app (localhost:3000) rather than to a specific file? – Mathieu K. Apr 19 '18 at 09:24
  • I hope here the index.html is the one which loads the react app. If you are developing locally then it depends on the development server you use. If you use webpack-dev-server, take a look at `historyFallback` option. – Panther Apr 21 '18 at 05:27
  • if still does not work, try this: location / { try_files $uri /index.html =404; } – Elizandro - SparcBR Oct 25 '20 at 16:02
  • For some reason this does not work. Probably there could be something else in the config preventing this. The answer by Ricardo https://stackoverflow.com/a/64815076/3153786 works! – qwertynik Dec 12 '20 at 11:48
  • if you are wondering where to find nginx.conf file, then its located at "/etc/nginx/nginx.conf" – aumiom Jun 06 '22 at 10:01
  • Okay! firs thing first, i was facing the same issue and didnt got resolve as I was doign the chnages in http server block, make sure u do the changes in http server 443 block. thanks me later !! – Shivam Sharma Oct 16 '22 at 13:54
  • 1
    This is the most important information for your react app to work. The answered guys must be genius !! – indianwebdevil Nov 12 '22 at 04:13
61

The answers given here are correct. But, I was struggling with this when trying to deploy my React Application in a docker container. The problem was on, how to change the nginx configs inside a docker container.

Step 1: Prepare your Dockerfile

# Stage 1
FROM node:8 as react-build
WORKDIR /app
COPY . ./
RUN yarn
RUN yarn build

# Stage 2 - the production environment
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=react-build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

See line with command: COPY nginx.conf /etc/nginx/conf.d/default.conf. Here, we are telling Docker to copy the nginx.conf file from the docker host, to the docker container.

Step 2: Have a nginx.conf file in your application root folder

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri /index.html;                 
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

Step 3: Now build the docker image and run it

$ docker build . -t react-docker

This should build your docker image successfully. To check that, run

$ docker images

Now run

$ docker run -p 8000:80 react-docker 

and navigate to http://localhost:8000

This was inspired by this blog.

Keet Sugathadasa
  • 11,595
  • 6
  • 65
  • 80
40

For me the solution was:

location / {
            root /var/www/myapp/build;
            index index.html;
            try_files $uri /index.html$is_args$args =404;
    }
10

After many hours I finally got this working with:

try_files $uri /index.html$is_args$args =404;

The last arg (=404) is what made this work.

5

This worked for me while using nginx to serve react:

Edit the location section of the nginx.conf(or can also be default.conf) file to be as below. The nginx.conf file is found somewhere in /etc/nginx/sites-available/yoursite

location / {
   # First attempt to serve request as file, then
   # as directory, then redirect to index(angular) if no file found.
   try_files $uri $uri/ /index.html;
}

The full nginx.conf configuration will therefore be as below:

   server {
        listen 80 default_server;
        server_name  localhost;

        root   /usr/share/nginx/html;
        index  index.html index.htm;

        location /{
            try_files $uri $uri/ /index.html;
        }
    }
Elijah Baraza
  • 291
  • 4
  • 4
2

The problem comes when you are in a path for eg http:///some/path and you hit refresh you get a 404 error page. This extra line in the ngnix configuration could solve the issue.

location /{
                try_files $uri $uri/ /index.html?/$request_uri;
          }

After adding do a nginx service restart.

Codemaker2015
  • 12,190
  • 6
  • 97
  • 81
1

This worked for me

location /{
try_files $uri $uri/ /index.html$is_args$args;
}
Mahi
  • 97
  • 2
  • 9
0

If your are using nextjs like I am, maybe you need add this to next.config.js

module.exports = {
  trailingSlash: true,
}

And build your project again.

For reference: https://nextjs.org/docs/api-reference/next.config.js/exportPathMap#adding-a-trailing-slash

ding van
  • 315
  • 2
  • 4
  • 14
-1

try using following commands in sites-enabled

sudo nano /etc/nginx/sites-available/Your_WEB_Folder

try_files $uri $uri/ /index.html;

Get me some towers now!

Anupam Maurya
  • 1,927
  • 22
  • 26