T
TanStack2y ago
dependent-tan

Help with understanding NotFoundRoute and routeTree

Hi folks, new to tanstack router here. I have a basic Vite/React/TS project. I'm having a having a bit of a hard time trying to figure out how to only render a "Not Found" component and subsequently what role the routeTree plays in this regard. Here's what I mean Following is my main.tsx
const notFoundRoute = new NotFoundRoute({
getParentRoute: () => rootRoute,
component: () => <div>Not found</div>,
});
const router = new Router({ routeTree, notFoundRoute });
declare module '@tanstack/react-router' {
interface Register {
router: typeof router;
}
}
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<RouterProvider router={router} />
<App />
</React.StrictMode>
);
const notFoundRoute = new NotFoundRoute({
getParentRoute: () => rootRoute,
component: () => <div>Not found</div>,
});
const router = new Router({ routeTree, notFoundRoute });
declare module '@tanstack/react-router' {
interface Register {
router: typeof router;
}
}
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<RouterProvider router={router} />
<App />
</React.StrictMode>
);
Problem is if you look at the screenshot, it's rendering "Not Found" on top of the root component. If I wanted to show a full-on "Not Found" page when a user hits, let's say a "localhost:3000/dummy" route, what changes would I have to make? I'm assuming I'm missing something fundamental in my routeTree file, which I haven't started adding to anything yet since I just spun up the project. For context though, here's my routTree file and the _root.tsx file
// This file is auto-generated by TanStack Router

// Import Routes

import { Route as rootRoute } from './routes/__root'

// Create/Update Routes

// Populate the FileRoutesByPath interface

declare module '@tanstack/react-router' {
interface FileRoutesByPath {}
}

// Create and export the route tree

export const routeTree = rootRoute.addChildren([])
// This file is auto-generated by TanStack Router

// Import Routes

import { Route as rootRoute } from './routes/__root'

// Create/Update Routes

// Populate the FileRoutesByPath interface

declare module '@tanstack/react-router' {
interface FileRoutesByPath {}
}

// Create and export the route tree

export const routeTree = rootRoute.addChildren([])
root.tsx
import { RootRoute, Outlet } from '@tanstack/react-router';
import { TanStackRouterDevtools } from '@tanstack/router-devtools';

export const Route = new RootRoute({
component: () => {
return (
<>
<Outlet />
<TanStackRouterDevtools position="bottom-right" />
</>
);
},
});
import { RootRoute, Outlet } from '@tanstack/react-router';
import { TanStackRouterDevtools } from '@tanstack/router-devtools';

export const Route = new RootRoute({
component: () => {
return (
<>
<Outlet />
<TanStackRouterDevtools position="bottom-right" />
</>
);
},
});
Some pointers would be really appreciated!
No description
14 Replies
dependent-tan
dependent-tanOP2y ago
I have looked into some of the existing examples, such as the authenticated routes one - https://tanstack.com/router/v1/docs/examples/react/authenticated-routes-context But I'm not entirely sure what the update method here is doing. From the docs, I do see it says
Updates the route instance with new options and returns the route instance (but with updated types to reflect the new options)
But it's not clear to me as to why we'd have to define the route (and its details), take login from that linked example, in the routes/login.tsx file but then "update" it in the routeTree.gen.ts file.
React Router Authenticated Routes Context Example | TanStack Router...
An example showing how to implement Authenticated Routes Context in React Router
national-gold
national-gold2y ago
Make sure you are adding the notFoundRoute to the RouterProvider
<RouterProvider router={router} notFoundRoute={notFoundRoute} />
<RouterProvider router={router} notFoundRoute={notFoundRoute} />
dependent-tan
dependent-tanOP2y ago
it still renders "Not Found" followed by the App component, which is the vite+react logo. Is it happening because I don't have anything configured in my routeTree yet? I think I see the problem.
<React.StrictMode>
<RouterProvider router={router} />
<App />
</React.StrictMode>
<React.StrictMode>
<RouterProvider router={router} />
<App />
</React.StrictMode>
And then App.tsx had the code to render the vite+react logo from the screenshot above <h1>Vite + React</h1> However, App.tsx wasn't tied to any route. Which explains why it was rendering even after I added a dummy route with a dummy one-line text. Also, I didn't realize that the content within the routeTree file gets generated as we add more routes. I was thinking I'd have to add stuff manually there.
national-gold
national-gold2y ago
Your Router provider needs to be a child of App
dependent-tan
dependent-tanOP2y ago
@Wick Lurker I've done that, as follows -
const notFoundRoute = new NotFoundRoute({
getParentRoute: () => rootRoute,
component: () => <div>Not found</div>,
});

const router = new Router({ routeTree, notFoundRoute });

declare module '@tanstack/react-router' {
interface Register {
router: typeof router;
}
}

function App() {
return <RouterProvider router={router} />;
}

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
const notFoundRoute = new NotFoundRoute({
getParentRoute: () => rootRoute,
component: () => <div>Not found</div>,
});

const router = new Router({ routeTree, notFoundRoute });

declare module '@tanstack/react-router' {
interface Register {
router: typeof router;
}
}

function App() {
return <RouterProvider router={router} />;
}

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
However, the problem I see now is that if I hit just "/" and nothing else, I'm getting the "Not Found" component (as shown in the screenshot). Following is my __root.tsx
export const Route = new RootRoute({
component: () => {
return (
<>
<Outlet />
<TanStackRouterDevtools position="bottom-right" />
</>
);
},
});
export const Route = new RootRoute({
component: () => {
return (
<>
<Outlet />
<TanStackRouterDevtools position="bottom-right" />
</>
);
},
});
Feel like I'm missing something basic here that's not obvious to me. Any thoughts?
No description
national-gold
national-gold2y ago
Have you added at least one normal route? If not, then nothing is matched and you'll see the not found route as expected
dependent-tan
dependent-tanOP2y ago
yes, I've added one normal route, like so - src/routes/docs.tsx
export const Route = new FileRoute('/docs').createRoute({
component: Docs,
});

function Docs() {
return (
<div>
<span>This is the docs page</span>
</div>
);
}

export default Docs;
export const Route = new FileRoute('/docs').createRoute({
component: Docs,
});

function Docs() {
return (
<div>
<span>This is the docs page</span>
</div>
);
}

export default Docs;
This renders just fine when I'm hitting the "/docs" route, but then I navigate to "/" and it renders the not found as above.
dependent-tan
dependent-tanOP2y ago
looking at the debugger, it explains why I'm getting the "Not Found" when hitting "/", but I'm not sure how to get around it. Is it happening because I'm setting up my notFoundRoute at the App level, and it instead needs to be on an individual route level? this is what I have, in case it helps with context -
const notFoundRoute = new NotFoundRoute({
getParentRoute: () => rootRoute,
component: () => <div>Not found</div>,
});

const router = new Router({ routeTree, notFoundRoute });

declare module '@tanstack/react-router' {
interface Register {
router: typeof router;
}
}

function App() {
return <RouterProvider router={router} />;
}

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
const notFoundRoute = new NotFoundRoute({
getParentRoute: () => rootRoute,
component: () => <div>Not found</div>,
});

const router = new Router({ routeTree, notFoundRoute });

declare module '@tanstack/react-router' {
interface Register {
router: typeof router;
}
}

function App() {
return <RouterProvider router={router} />;
}

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
No description
national-gold
national-gold2y ago
You need to add notFoundRoute to the RootProvider, as explained above. <RouterProvider router={router} notFoundRoute={notFoundRoute} />
dependent-tan
dependent-tanOP2y ago
The issue was that I was missing the index file corresponding to the root route. I don’t believe we need to pass “notFoundRoute = {notFoundRoute}” here with the RouteProvider, as we’re already doing that when instantiating the Router. Thanks for looking into it though!
rising-crimson
rising-crimson2y ago
hey, i am also struggling with the file based router and not found routes. On the root route it is working fine. When I enter like /manager, it succeeds. when i type a route that doesnt exist i get the notFound Component. But if i type something like /manager/dashboard/test and i have a route like /manager/dashboard then i always land on the /manager/dashboard route. in the dev tools the /404 match is listed, but it is not rendered. anyone have a guess? I also tried to change the naming of the file to route.tsx or index.tsx to see the difference between them. but there are none somehow. My folder tree is like this: __root.tsx _layout.tsx /manager/index.tsx /manager/$.tsx /manager/dashboard/route.tsx
No description
absent-sapphire
absent-sapphire2y ago
experiencing exactly the same problem as you, not sure why it isn't working
dependent-tan
dependent-tanOP2y ago
In my case, I was able to fix it by ensuring that there’s an index file for the root route, so /routes/_root.tsx /routes/index.tsx @LenB your screenshot from above makes me think that the 404 is matching the root route because there’s probably not an index file for the root route?
rising-crimson
rising-crimson2y ago
@kylo i have an index file in root, i forgot to mention it

Did you find this page helpful?