Issue
I have the following basic example taken from the official react-router-dom
github page and adjusted:
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="parent/:id">
<Route index element={<FirstChild />} />
<Route path=":source" element={<SecondChild />} />
</Route>
<Route path="*" element={<NoMatch />} />
</Route>
</Routes>
and the layout
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/parent/2">FirstChild</Link>
</li>
<li>
<Link to="/parent/2/editor">SecondChild</Link>
</li>
</ul>
</nav>
So when I hit SecondChild
route link I navigate to myDomain/parent/2/editor
.
What I would like to achieve is in case the user goes manually in the browser url and erases or modifies the last param, which in my case is editor
. If the users writes editor2
and hits ENTER, how do I redirect the user to myDomain/parent/2/editor
? Does anyone know if this is possible in react-router-dom@6
?
Edit
source
is dynamic. So there are other pages with the route "/parent/:id/...". There is for instance
/parent/:id/labelbook
And I want to redirect to the correct route in case user modifies again labelbook or editor in the two different scenarios to the correct route param. In the future a third scenario maybe will be added.
In react router-dom 5
I could do that by adding ?
next to the param but now this is gone. I could do
<Route path=":source?" element={<SecondChild />} />
and get the job done.
Solution
You can render a redirect at that nested level.
First, since it's unclear what exactly you want to render at the second nested level I'll provide a couple examples.
Example #1: The SecondChild
component is rendered exactly on "/parent/:id/editor"
and you want to redirect any other nested route to there.
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="parent/:id">
<Route index element={<FirstChild />} />
<Route path="editor" element={<SecondChild />} />
<Route path="*" element={<Navigate to="../editor" replace />} />
</Route>
<Route path="*" element={<NoMatch />} />
</Route>
</Routes>
Example #2: The SecondChild
component is rendered on "/parent/:id/:source"
and you explicitly want to redirect from "/parent/:id/editor2"
to "/parent/:id/editor"
.
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="parent/:id">
<Route index element={<FirstChild />} />
<Route path=":source" element={<SecondChild />} />
<Route
path="editor2"
element={<Navigate to="../editor" replace />}
/>
</Route>
<Route path="*" element={<NoMatch />} />
</Route>
</Routes>
Example #3:
If you've a list of specific ":source"
values you want to match then you should render explicit routes for each. If the SecondChild
component depends on what a "source" value is then I'd suggest passing it in as a prop. Any route that isn't explicitly matched will be rendered to the "*"
NoMatch
route.
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="parent/:id">
<Route index element={<FirstChild />} />
<Route path="editor" element={<SecondChild source="editor" />} />
<Route path="labelbook" element={<SecondChild source="labelbook" />} />
... etc ...
<Route path="*" element={<NoMatch />} />
</Route>
</Routes>
Answered By - Drew Reese
Answer Checked By - - Marie Seifert (ReactFix Admin)