8

I'm setting up a 404 page. It will live at /404 and I will be using <Navigate path='/404' /> for any unknown routes. This all works fine, but I'd also like to display the URL details and even more so log the bad links. To do that, I need access to the previous route details.

There is a similar article, but it discusses navigating history, not displaying the history information.

How to go back to previous route in react-router-dom v6

I've tried various combinations of the following, trying to grab details from useLocation and passing as state, but it throws the error: Error: useLocation() may be used only in the context of a <Router> component.

<BrowserRouter>
  <Routes>
    <Route path="/" element={<Homepage />} />
    <Route path="/404" element={<NoPageFound />} />
    <Route path="*" element={<Navigate to='/404' state={{ prevRoute: useLocation() }} />} />
  </Routes>
<BrowserRouter>

Is there some other way I can access the previous route details from within <NoPageFound /> for display/logging purposes?

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
Adam Youngers
  • 6,421
  • 7
  • 38
  • 50

1 Answers1

7

The issue with using the useLocation hook directly in the Navigate component in the Route is that it is functioning in the outer scope of the component rendering the BrowserRouter.

You could just create a React component that grabs the current location and passes that along to a rendered Navigate component.

const UnkownRouteHandler = ({ to }) => {
  const prevRoute = useLocation();
  return <Navigate to={to} state={{ prevRoute }} replace />
};

...

<BrowserRouter>
  <Routes>
    <Route path="/" element={<Homepage />} />
    <Route path="/404" element={<NoPageFound />} />
    <Route path="*" element={<UnkownRouteHandler to="/404" />} />
  </Routes>
<BrowserRouter>

In this way it is similar to how you would grab the currently accessed route of a protected route before an auth redirect occurs, passing the location as a "referrer" so after the auth completes you can redirect users back to the route they originally tried to access. In your case though you are simply wanting to capture what the unhandled route was, and forward for handling/logging/etc.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • That is interesting. It was my hope that useLocation would just expose previous route by default. – Adam Youngers Nov 19 '21 at 02:15
  • 1
    What does the `replace` do in the Navigate? – Adam Youngers Nov 19 '21 at 02:54
  • 2
    @AdamYoungers `replace` is a boolean value to indicate the navigation should be a `REPLACE` instead of a `PUSH`, in other words, it's a redirect instead of a regular navigation, replacing the current history entry instead of pushing a new entry on the history stack. – Drew Reese Nov 19 '21 at 03:02