React router relies on remix-run/history and History Web API.
Alas, neither of them let access the history stack. remix-run/history allows to listen for location changes, but this can't be accessed from the router.
So the conclusion is: there is no built-in way to know the URL of the previous page. If you need it, you will have to build something on your own.
Here is a starter. First prepare a context to provide your history stack:
const myHistoryContext = createContext();
function MyHistoryProvider({ children }) {
const [myHistory, setMyHistory] = useState([]);
const push = (location) => setMyHistory([...myHistory, location]);
return (
<myHistoryContext.Provider value={{ myHistory, push }}>
{children}
</myHistoryContext.Provider>
);
}
const useMyHistory = () => useContext(myHistoryContext);
A container to keep trace of navigation: this will be used as a nesting route for every pages. The container keeps history up to date by pushing new locations:
function Container() {
const { push } = useMyHistory();
const location = useLocation();
useEffect(() => {
push(location.pathname);
}, [location]);
return <Outlet />;
}
Some pages to be used with the container. Home will display the path of the previous page:
function Home() {
const { myHistory } = useMyHistory();
const previous = myHistory[myHistory.length - 2];
return <h1>Home {previous}</h1>;
}
function Contact() {
return <h1>Contact</h1>;
}
function About() {
return <h1>About</h1>;
}
Everything wrapped in App:
function App() {
return (
<MyHistoryProvider>
<BrowserRouter>
<Link to="/">Home</Link>
<Link to="/contact">Contact</Link>
<Link to="/about">About</Link>
<Routes>
<Route path="/" element={<Container />}>
<Route path="/" element={<Home />} />
<Route path="/contact" element={<Contact />} />
<Route path="/about" element={<About />} />
</Route>
</Routes>
</BrowserRouter>
</MyHistoryProvider>
);
}
A working example on stackblitz: https://stackblitz.com/edit/react-ts-4qykui?file=App.tsx
Some drawbacks:
- You will only be able to track location changes inside your app. You won't be able to know the external url that led to your app.
- Reloading the page will clean
myHistory
.
- This starter only covers pushing into the stack. Depending on your use case, you might need to handle popping from the stack, e.g. when using the back/forward buttons in your browser.