I have the following routing config:
<Router>
<NotFound default />
<ResourcesContainer path="/resources" />
<ResourceContainer path="/resources/:id" />
...
</Router>
This catches any routes that are not handled, and renders the <NotFound />
component at the URL that wasn't found, so if I type example.com/blah
, I see the <NotFound />
component rendered, and in the address bar I see example.com/blah
. I also use this URL on the page to display a message:
The page 'example/blah' was not found.
So far so good. However I also need to handle 404s from within in /resources/*
routes. My <ResourcesContainer/>
component uses the last part of the path to hit a GraphQL API for a resource with that id. If the API returns to tell the client that resource doesn't exist, I would like to mimic the behaviour outlined above. However, I don't have a page to navigate to. I could duplicate the <NotFound />
route and give it an explicit path
of /404
, then navigate to that. However the URL would then be /404
and not the original resources/*
path that wasn't found.
The following solves part of the problem, giving me a page to redirect ot, but means the URL is rewritten to /404
in all cases:
<Router>
<ResourcesContainer path="/resources" />
<ResourceContainer path="/resources/:id" />
<NotFound path="/404" />
<Redirect noThrow from="*" to="/404" />
...
</Router>
How can I set this up so that I can navigate
to the <NotFound />
route without losing the original URL?
Your best option is to change render method of
ResourceContainer
to renderNotFound
if resource is not found.However, if you don't want to make changes to
ResourceContainer
, you can wrap it with an error boundary like this:And use it like:
Your
ResourceContainer
can throw an errorNotFoundErrorBoundary
can identify and that can signal that resource is not found and it should renderNotFound
page instead of the children.To be clear, I am not encouraging you to use ErrorBoundary. In my opinion, it will overcomplicate things. I just present you the information, how you use it is up to you. Also it may be useful to you in another context depending on the use case.