diff --git a/packages/react-router/src/renderRouteNotFound.tsx b/packages/react-router/src/renderRouteNotFound.tsx
index 225a013beae..ab2fd4c4945 100644
--- a/packages/react-router/src/renderRouteNotFound.tsx
+++ b/packages/react-router/src/renderRouteNotFound.tsx
@@ -16,20 +16,25 @@ export function renderRouteNotFound(
route: AnyRoute,
data: any,
) {
- if (!route.options.notFoundComponent) {
- if (router.options.defaultNotFoundComponent) {
- return
- }
+ let routeWithNotFound: AnyRoute | undefined = route
+ while (routeWithNotFound && !routeWithNotFound.options.notFoundComponent) {
+ routeWithNotFound = routeWithNotFound.parentRoute
+ }
+
+ if (routeWithNotFound?.options.notFoundComponent) {
+ return
+ }
- if (process.env.NODE_ENV === 'development') {
- warning(
- route.options.notFoundComponent,
- `A notFoundError was encountered on the route with ID "${route.id}", but a notFoundComponent option was not configured, nor was a router level defaultNotFoundComponent configured. Consider configuring at least one of these to avoid TanStack Router's overly generic defaultNotFoundComponent (
Not Found
)`,
- )
- }
+ if (router.options.defaultNotFoundComponent) {
+ return
+ }
- return
+ if (process.env.NODE_ENV === 'development') {
+ warning(
+ false,
+ `A notFoundError was encountered on the route with ID "${route.id}", but a notFoundComponent option was not configured, nor was a router level defaultNotFoundComponent configured. Consider configuring at least one of these to avoid TanStack Router's overly generic defaultNotFoundComponent (Not Found
)`,
+ )
}
- return
+ return
}
diff --git a/packages/react-router/tests/not-found.test.tsx b/packages/react-router/tests/not-found.test.tsx
index ce8bdf1207f..a0267ede0a7 100644
--- a/packages/react-router/tests/not-found.test.tsx
+++ b/packages/react-router/tests/not-found.test.tsx
@@ -245,3 +245,75 @@ test('defaultNotFoundComponent and notFoundComponent receives data props via spr
const errorMessageComponent = await screen.findByTestId('message')
expect(errorMessageComponent).toHaveTextContent(customData.message)
})
+
+test('pathless layout route notFoundComponent is used when child has none (issue #6351)', async () => {
+ const rootRoute = createRootRoute({
+ component: () => (
+
+
+
+ ),
+ })
+
+ const authenticatedRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ id: '_authenticated',
+ component: () => (
+
+
+
+ ),
+ notFoundComponent: () => (
+
+ Authenticated Not Found
+
+ ),
+ })
+
+ const agentsRoute = createRoute({
+ getParentRoute: () => authenticatedRoute,
+ path: 'agents',
+ component: () => (
+
+
+
+ ),
+ })
+
+ const agentsIndexRoute = createRoute({
+ getParentRoute: () => agentsRoute,
+ path: '/',
+ component: () => Agents Index
,
+ })
+
+ const skillAgentRoute = createRoute({
+ getParentRoute: () => agentsRoute,
+ path: 'skill-agent',
+ component: () => Skill Agent
,
+ })
+
+ const router = createRouter({
+ routeTree: rootRoute.addChildren([
+ authenticatedRoute.addChildren([
+ agentsRoute.addChildren([agentsIndexRoute, skillAgentRoute]),
+ ]),
+ ]),
+ history,
+ defaultNotFoundComponent: () => (
+ Default Not Found
+ ),
+ })
+
+ window.history.replaceState(null, '', '/agents/non-existent')
+
+ render()
+ await router.load()
+
+ const notFound = await screen.findByTestId(
+ 'authenticated-not-found',
+ {},
+ { timeout: 1000 },
+ )
+ expect(notFound).toBeInTheDocument()
+ expect(screen.queryByTestId('default-not-found')).not.toBeInTheDocument()
+})