Hera Zeus
Hera Zeus

Reputation: 163

Create private route and public route with 404 not found page

I use react router v5 to make an app router. I want to make a 404 not found page when user goes to any link that not listed in the router whether they are logged in or not.

Here is my app router:

<Router>
  <Switch>
    <Route exact path="/" component={Home} />
    <Route exact path="/redirect" component={Pages.Redirect} />
    <Route exact path="/login" restricted component={Pages.Login} />
    <Route path="*" component={Pages.NotFound} />
    <Navigation>
      <PrivateRoute exact path="/dashboard" component={Pages.Dashboard} />
      <PrivateRoute exact path="/my-playlist" component={Pages.MyPlaylist} />
      <PrivateRoute exact path="/new-released" component={Pages.NewReleased} />
      <PrivateRoute exact path="/search" component={Pages.CreatePlaylist} />
      <PrivateRoute exact path="/profile" component={Pages.Profile} />
    </Navigation>
  </Switch>
</Router>

The problem is, when I goes to dashboard, profile, search, etc. The page will render 404 not found page, not the correct one. And if I type any url, the page will render <Navigation> component instead of 404 not found page.

How to solve this?

Update:

Everything works fine now. I wrap my privaterouter with the <Navigation> component so every private route is render inside the <Navigation>.

Here is the privateRouter:

const PrivateRoute = ({ component: Component, ...rest }: any) => (
  <Navigation>
    <Route
      {...rest}
      render={(props) =>
        isLoggedIn() ? <Component {...props} /> : <Redirect to="/login" />
      }
    />
  </Navigation>
);

Upvotes: 1

Views: 892

Answers (1)

Drew Reese
Drew Reese

Reputation: 202872

Issue

The <Route path="*" component={Pages.NotFound} /> matches all routes and renders. Nothing in the Switch after it is reachable.

Solution

  • Move the Navigation into a route outside the Switch with an array of paths it should be rendered with.
  • Order the routes in inverse order of path specificity.

Example:

<Router>
  <Route
    path={["/dashboard", "/my-playlist", "/new-released", "/search", "/profile"]}
    component={Navigation}
  />
  <Switch>
    <Route path="/redirect" component={Pages.Redirect} />
    <Route path="/login" component={Pages.Login} />
    <PrivateRoute path="/dashboard" component={Pages.Dashboard} />
    <PrivateRoute path="/my-playlist" component={Pages.MyPlaylist} />
    <PrivateRoute path="/new-released" component={Pages.NewReleased} />
    <PrivateRoute path="/search" component={Pages.CreatePlaylist} />
    <PrivateRoute path="/profile" component={Pages.Profile} />
    <Route exact path="/" component={Home} />
    <Route path="*" component={Pages.NotFound} />
  </Switch>
</Router>

Upvotes: 2

Related Questions