'Netlify renders 404 on page refresh (using React and react-router)

I have deployed my site with Netlify, and I’m having trouble with the routing.

Here is my website: https://redux-co.netlify.com/

And my GitHub repo: https://github.com/jenna-m/redux-co

Specifically, if a user navigates to any page besides the home page and refreshes the page, the default Netlify 404 renders. From the 404 page, if I navigate back to the home page and refresh, the home page is rendered.

Also, my custom 404 page isn’t working as it does when I’m on localhost:3000, but I would like to get this refresh issue figured out first before dealing with my custom 404 component.

I’m using React and react-router, and I understand that since I’m using react-router, my website won’t deploy right out of the box.


This is my _redirects file, which is in the /public folder with my index.html file:

/*    /index.html   200

This is my “build” located in package.json:

…
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build && cp build/index.html build/404.html",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }
…

I have read about other people experiencing this and what they’ve done to overcome the problem. This is what I’ve referenced so far…

https://www.freecodecamp.org/news/how-to-deploy-a-react-application-to-netlify-363b8a98a985/

https://hugogiraudel.com/2017/05/13/using-create-react-app-on-netlify/

This person was using Vue and not React, but I gave these solutions an attempt anyway:

https://github.com/vuejs/vuepress/issues/457#issuecomment-390206649

https://github.com/vuejs/vuepress/issues/457#issuecomment-463745656



Solution 1:[1]

This was simple and it worked for me. I found this link https://create-react-app.dev/docs/deployment#netlify

So as suggested by that link, I added a _redirects file inside the /public folder like /public/_redirects. I then pasted /* /index.html 200 into the _redirects file. I did all that in my VS Code, after which I pushed to github and then ofcourse my netlify re-deploys automatically everytime I push to github. My problem was solved and refresh nolonger brings the 404 error.

In my package.json, the build section looks like this;

"scripts": {
   "start": "react-scripts start",
   "build": "react-scripts build",
   "test": "react-scripts test",
   "eject": "react-scripts eject"
}

Note: Some articles say that you need to add _redirects in the build folder, but then build folder is not among what gets pushed to github in my case, so that's why adding _redirects to public folder worked better for me, as the public folder can be pushed along with my code.

Solution 2:[2]

Add netlify.toml file to the root directory of your project and paste the following code in it:

[[redirects]]
  from = "/*"
  to = "/"
  status = 200

push and redeploy your app and it's done.

Solution 3:[3]

Remove _redirects from your public folder and move netlify.toml to the root of your git repo, more info. Also remove from build script && cp build/index.html build/404.html - you don't need that any more

Solution 4:[4]

I was having a similar issue so I created _redirects file in the public folder and put the following code

/* /index.html 200

build files again npm run build and worked for me resource for similar issue

Solution 5:[5]

I had the same refresh issue in netlify. For me it was a series of changes. I had before my react configuration pointing to a subfolder (/sandbox/appfolder) to use in my hosting sandbox (I hope I can revert to that changing the parameters below). To be able to do a continuous deploy in netlify I did the following inspired in other answers. When using my own hosting sandbox, I didn't have the _redirects and the homepage pointed to the subfolder.

EDIT: to run from my site's subfolder I had to edit .htaccess to RewriteRule ^ /sandbox/myapp/index.html [L] and package.json to "homepage": "/sandbox/myapp"

in /package.json:

"homepage": "/",

in /public/.htaccess

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 ^ /index.html [L]

in my main component src/App.js:

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

in public/index.html

<base href="%PUBLIC_URL%/">

and finally as mentioned in /public/_redirects

/* /index.html 200

Solution 6:[6]

2022 Update:

If adding _redirects file did not work for me.(React JS)

For me the solution was to create netlify.toml file in the base directory of my react project. Then adding following.

[[redirects]] from = "/*" to = "/" status = 200

Solution 7:[7]

For me worked the next solution. First of all create a file on your public folder named _redirects (no extension, just pure text) and type -> /* /index.html 200 in it. Then in your package.json file set at very top the property { homepage: "YOUR PUBLIC URL", ...rest of the properties } and in the index.html file add <head>...<base href="YOUR PUBLIC URL">...</head>. Got the answer from this blog post, user called hrishikesh.

Solution 8:[8]

enter code hereUsing HashRouter instead of BrowserRouter solves the problem

import { HashRouter as Router, Switch, Route } from 'react-router-dom'
//instead of 
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'

Solution 9:[9]

create _redirects in the root directory mention your app routes inside the _redirects file, for example: /home /terms-and-condition

that's it.

Solution 10:[10]

try this

faced this same issue previously, founded that it was because of the proxy that I was using to connect to my backend server. Let's say the backend app is located at this URL example.com. So, instead of mentioning this as a proxy field in package.json, I would suggest putting the link in your functions only.

avoid this

{
  "name": "frontend",
  "version": "0.1.0",
  "proxy": "https://example.com",
  "private": true,
....
....
}

If, using redux then in put your backend url in actions with axios or fetch. (Also, try deleting the package-lock.json file and then push the code without it on your Github and then connect it to netifly and then re-deploy your site)

Example code (notice api call)

export const listArticles = () => async (dispatch, getState) => {
    try {
        dispatch({
            type: ARTICLES_LIST_REQUEST
        })

        // api call
        const { data } = await axios.get("https://example.com/api/articles/")

        dispatch({
            type: ARTICLES_LIST_SUCCESS,
            payload: data
        })

    } catch (error) {
        dispatch({
            type: ARTICLES_LIST_FAIL,
            payload: error.response && error.response.data.detail ? error.response.data.detail : error.message
        })
    }
}

My package.json file

{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.10",
    "@testing-library/react": "^11.2.6",
    "@testing-library/user-event": "^12.8.3",
    "axios": "^0.21.1",
    "mdbreact": "^5.0.2",
    "react": "^17.0.2",
    "react-bootstrap": "^1.5.2",
    "react-dom": "^17.0.2",
    "react-redux": "^7.2.3",
    "react-router-bootstrap": "^0.25.0",
    "react-router-dom": "^5.2.0",
    "react-scripts": "4.0.3",
    "redux": "^4.0.5",
    "redux-devtools-extension": "^2.13.9",
    "redux-thunk": "^2.3.0",
    "web-vitals": "^1.1.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

Solution 11:[11]

In my case I added the _redirects file and that did not work. I played with my CI settings again and in my build command I wrote CI = npm run build but then in the Public Directory field I wrote build and then triggered a redeploy and my site finally worked!

Solution 12:[12]

I tried the _redirects file and the netlify.toml updates but was still getting the 404. For me, the fix was to update the Build Settings on netlify.com. I think changing the Publish Directory to ./build was the fix:

netlify build settings

By the way, I followed some suggestions on stack/elsewhere to add a tag in my index.html file, and also to update the homepage in my package.json. Neither of these things helped and may have also messed up my fetch requests. (just in case anyone else was having similar issues)

Solution 13:[13]

If you ran into this issue for React Native Web, using an Expo-managed workflow, this solution fixed the problem:

  1. Create a netlify.toml in the project's root directory.

  2. Add the following code in the netlify.toml file:

    [[redirects]]
    from = "/*"
    to = "/index.html"
    status = 200
  1. Run the netlify deploy command in your terminal.

Solution 14:[14]

This is my _redirects file, which is in the /public folder with my index.html file:

_redirects in

/* /index.html 200

and then re-deploy your site in Netlify.

Thanks!