In React Router v6, how can I go back to the previous page using <Link> instead of useNavigate().
// Instead of this...
<button onClick={() => navigate(-1)}>
// ...it needs to be this:
const previousPage = ???
<Link to={previousPage}>Go back</Link>
I don't know what URL to pass to the Link.
Why is it important: Changing it to <Link> would allow me to use <a href="xxxx"> instead of a <button>, which is the most accessible way of creating links between pages. (More about button vs links). For example, it allows users to:
Update: I've created a codesandbox to help you find the solution.
Update 2: Based on the answers and some research, I created a GitHub issue to react-router
Update 3: I've added my own answer below.
It's not a bug in react-router-dom@6 and not really anything a Link is meant to do, i.e. it's just an anchor tag under the hood, and links to a path as a declarative navigation action. This is fundamentally different than an imperative action like history.go(1) or history.back() (i.e. history.go(-1)) where you are imperatively saying to navigate forward/backward through the history stack.
In react-router-dom@6, however, you can navigate relative to the current path. ".." will navigate "back" one path segment for any Route components rendered within the current Routes component. I.E. from "/destiny" back to "/" with the same Routes component.
Example:
import { Link } from 'react-router-dom';
export default function Destiny() {
return (
<div>
<h1>Destiny Page</h1>
<Link to={'..'}>Go back</Link>
<br />
<Link to="/">Go Home ("/")</Link>
</div>
);
}
Note that this isn't the equivalent of navigate(-1) as it isn't transitioning through the history stack, so it's not a true back navigation. If you want to do a true back navigation then you'll want to add an onClick handler to the Link and prevent the default event action and handle issuing an imperative back navigation.
Example:
import { useNavigate, Link } from 'react-router-dom';
export default function Destiny() {
const navigate = useNavigate();
return (
<div>
<h1>Destiny Page</h1>
<Link
to={'..'}
onClick={(e) => {
e.preventDefault();
navigate(-1);
}}
>
Go back (-1)
</Link>
<br />
<Link to="/">Go Home ("/")</Link>
</div>
);
}
As far as I know, it's impossible to have a fully accessible "Go Back" link with:
<Link to={-1}>Go back</Link>
// or
<button onClick={() => navigate(-1)}>Go back</button>
It's not fully accessible for 2 reasons:
For 1) I found a workaround:
const router = useRouter(); // next/router
function handleGoBack() {
// 💡 Verify if previous page exists before using router.back
const hasPreviousPage = window.history.length > 1;
if (hasPreviousPage) {
router.back();
} else {
// fallback to a meaningful route.
router.push("/");
}
}
<button onClick={handleGoBack}>
Go back
</button>
For 2) I didn't find any solution. My recommendation would be to avoid "go back" links using -1 whenever you can, in favor of using <Link> with a real URL to the possible previous page.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With