How to avoid 404 page in react-router?

Viewed 5224

I'm working on a simple example using React Router.

I created it using create-react-app

On a local server, each link goes well ex) localhost:3000/login, localhost:3000/ product, etc.

After deploying to my domain, I get a 404 error when I enter my link. ex) myDomain.com/login, myDomain.com/product

It looks good on the local server, so I think there's no problem with the source code.

Then, I received an answer to redirect to the index.html page when the 404, 403 ... etc page appears

Are localhost:3000 and localhost:3000/index.html the same?

On the main page (localhost: 3000 or myDomain.com), is well rendered.

In index.html (localhost: 3000 / index.html or myDomain.com/index.html) it only renders up to h1 tag above {Home}. Is something wrong from here?

Please help me T.T

App.js


class App extends Component{
  render(){        
    return (
      <div className="App">
        <Header/>
        <h1>asd</h1>
        <h1>asd</h1>
        <Route exact path = "/" component = {Home}/>
          <Route path = "/about" component = {About}/>
          <Route path = "/event" component = {Event}/>
          <Route path = "/qna" component = {QnA}/>
          <Route path = "/login" component = {Login}/>
          <Route path = "/join" component = {Join}/>
          <Route path = "/product" component = {Product}/>
      </div>
    );
  }
}

export default App;

Root.js


const Root = () => {
    return (
        <BrowserRouter>
            <App/>
        </BrowserRouter>

    );
};

export default Root;

3 Answers

You can wrap your route components in a switch component and render a default component if none match like below.

<Switch>
    <Route exact path = "/" component = {Home}/>
    <Route path = "/about" component = {About}/>
    <Route path = "/event" component = {Event}/>
    <Route path = "/qna" component = {QnA}/>
    <Route path = "/login" component = {Login}/>
    <Route path = "/join" component = {Join}/>
    <Route path = "/product" component = {Product}/>
    <Route component={NoMatch} />
</Switch>

Obviously you'd change the NoMatch component with whatever you'd want your default component to be.

You should add the basename to the BrowserRouter component in the root

ReactDOM.render(
  <BrowserRouter basename='/My-App/'>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </BrowserRouter>
  ,
  document.getElementById('root')
);

Also, you should make sure in 404 cases you are redirected to index.html because it's a SPA and everything is happening there, you do this by simply replacing this line with "build" script in package.json

 "build": "react-scripts build && cp build/index.html build/404.html",

I don't think this is your react app issue, rather it's how your app is deployed.

I hope you have deployed your app using production build (using npm run build). If so, this is most likely that your web server is not redirecting to the right entry.

You need to tell your web server(nginx or caddy whatever you are using) to point to /index.html when hitting 404. Here is a simple config for nginx.

https://www.barrydobson.com/post/react-router-nginx/

Related