Skip to content

Not Found in beforeLoad and Loader does not behave as expected #2139

@ViewableGravy

Description

@ViewableGravy

Describe the bug

As described in the steps below, It looks like the notFound error that can be thrown from beforeLoad or the loader is not properly causing the right route to render their notFound component.

If notFound is thrown in beforeLoad, the root route will ALWAYS be the one to render the not found component. Based on router dev tools (which I have inserted above the root route so they do not unmount in my example), it looks like this is because throwing a not found error in beforeLoad causes all parent routes to also become notFound and therefore the root handles it, meaning that no layout is rendered.

If notFound is thrown in a loader, assuming that the loader ran as a result of a navigation or preload, then the notFound behaviour works as expected. However, if the loader is running on the first render of the router, this error propagates to the root route and causes the entire page to show the not found component. Interestingly, in this case, the about route doesn't actually get marked as notFound in the router state, but for some reason the root route still handles the notFound instead of the about component.

image

Your Example Website or App

https://stackblitz.com/edit/tanstack-router-cxbsxj?file=src%2Froutes%2F__root.tsx

Steps to Reproduce the Bug or Issue

  1. Load app to index route and navigate to before-load-not-found route. The root route will handle the not found instead of about, despite about being a parent and rendering an Outlet ❌
  2. Load app to index route and navigate to loader-not-found route. The about route renders it's layout and a not found in the outlet position ✅
  3. Load the app to the loader-not-found route (navigate to that page and then refresh the page). The root route handles the not found ❌

Expected behavior

  1. Load app to index route and navigate to before-load-not-found route. The about route should render it's layout and in the outlet position, the default notFound component
  2. Load app to index route and navigate to loader-not-found route. The about route renders it's layout and a not found in the outlet position
  3. Load the app to the loader-not-found route (navigate to that page and then refresh the page). The about route should render it's layout and in the outlet poisition, the default notFound component

Screenshots or Videos

No response

Platform

  • OS: [Windows]
  • Browser: [Arc]
  • Version: [Tanstack/router: 1.48.1]

Additional context

I noticed this because during my implementation of the router, I've created a middleware function (to run in beforeLoad) to check if a route is enabled for the website our application is running as. Previously this used redirects and as far as I can tell, redirects work completely fine, but may just be luck, because with a redirect, it's not really staying on the same route, so even if the same incorrect matching was to propagate up the routes, it wouldn't really matter since it's going to be redirected anyway.

In my example, I moved the Tanstack Dev tools into the InnerWrap so that they stay mounted on a not-found, helps a little.

I've also tested the following cases which behave the same:

  1. defaultNotFoundComponent manually set (createRouter & RouterProvider)
  2. Explicit not found component on about route
  3. No component set on about route

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions