I'm building a multilingual website and having a problem with React Router.
Every path starts with /:lang
and continues with the path of the relevant page:
Like this:
"/:lang/profile"
"/:lang/stores"
"/:lang/products"
"/:lang"
I want to redirect to 404 page when path doesn't match to any of the paths of available pages.
Since all of the paths start with same thing, I need to use exact
attribute.
But since exact
check all routes before matching one, the Route with the "*"
path at the end always matches and page always redirects to 404 even with the existing paths. I tried "/:lang/*"
too, but nothing different happened. Is there any solution for this ?
CodePudding user response:
you need to wrap your all path, Route component={NotFound}
will get rendered if not found any
<BrowserRouter>
<Switch>
<Route exact path="/lang" component={Lang}/>
<Route exact path="/lang/profile" component={Profile}/>
<Route component={NotFound}/>
</Switch>
</BrowserRouter>
old way was, with Redirect
and then map that url to, this uses redirect feature,
<Switch>
<Route path="/404" component={NotFound} />
<Redirect to="/404" />
</Switch>
if you using react-router v6, Redirect is removed, but still you do Navigate with *, import {Navigate } from "react-router-dom";
import {Navigate } from "react-router-dom";
<Routes>
<Route path="/404" element={<div>Wrong 404 path/div>} />
<Route path="*" element={<Navigate replace to="/404" />} />
</Routes>
CodePudding user response:
It sounds like you may be rendering your routes into a router without the benefit of using the Switch
. While Router
will inclusively match and render all matching routes (thus sometimes requiring the exact
prop), the Switch
exclusively matches and renders the first matched route. Also note that in a Switch
that path order and specificity matter! Order the routes from more specific paths to less specific paths.
Example:
<Switch>
<Route path="/:lang/profile" component={Profile} />
<Route path="/:lang/stores" component={Stories} />
<Route path="/:lang/products" component={Products} />
<Route path="/:lang" component={Lang} />
<Route component={NotFound} />
</Switch>
Here the more specific paths will try to be matched first, then the less specific "/:lang" path, and if that doesn't match, the 404 component is rendered as a "catch-all" for anything that wasn't matched previously above it.