T
TanStack3y ago
absent-sapphire

How to implement dynamic routes?

Hey I'm wondering how I would implement dynamic routes. I looked at some GitHub Discussion and found a Discord threat but it seems to not work for me. I want to have a / index page and /issue/$id pages. /issue should just show a 404 page for now. The index page was easy to implement, but I'm unsure how I implement the dynamic issue route. In my issue.tsx file I have an issue TSX component and a not found component. I then created these two routes:
export const issueBaseRoute = new Route({
getParentRoute: () => rootRoute,
path: "/issue",
component: NotFound,
});

export const issueRoute = new Route({
getParentRoute: () => issueBaseRoute,
path: "$id",
parseParams: (params) => ({
id: z.number().parse(params.id),
}),
stringifyParams: ({ id }) => ({ id: id.toString() }),
component: IssueViewPage,
});
export const issueBaseRoute = new Route({
getParentRoute: () => rootRoute,
path: "/issue",
component: NotFound,
});

export const issueRoute = new Route({
getParentRoute: () => issueBaseRoute,
path: "$id",
parseParams: (params) => ({
id: z.number().parse(params.id),
}),
stringifyParams: ({ id }) => ({ id: id.toString() }),
component: IssueViewPage,
});
In my issue component I can then use this to get the issue id:
const { id: issueId } = useParams({ from: issueRoute.id });
const { id: issueId } = useParams({ from: issueRoute.id });
In my main.tsx I register all routes:
const routeTree = rootRoute.addChildren([indexRoute, issueBaseRoute, issueRoute]);

// Create the router using your route tree
const router = new Router({ routeTree });

// Register your router for maximum type safety
declare module "@tanstack/router" {
interface Register {
router: typeof router;
}
}

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
</QueryClientProvider>
</React.StrictMode>
);
const routeTree = rootRoute.addChildren([indexRoute, issueBaseRoute, issueRoute]);

// Create the router using your route tree
const router = new Router({ routeTree });

// Register your router for maximum type safety
declare module "@tanstack/router" {
interface Register {
router: typeof router;
}
}

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
</QueryClientProvider>
</React.StrictMode>
);
I don't get any type errors, but when I start my application I get this error in the dev tools:
Invariant failed: Duplicate routes found with id: /issue/$id
at invariant (tiny-invariant.js:12:11)
at router.ts:1014:9
at Array.forEach (<anonymous>)
at recurseRoutes (router.ts:1009:14)
at router.ts:1023:11
at Array.forEach (<anonymous>)
at recurseRoutes (router.ts:1009:14)
at Router.<anonymous> (router.ts:1065:5)
at Router.update (router.ts:361:24)
at new Router (router.ts:292:10)
Invariant failed: Duplicate routes found with id: /issue/$id
at invariant (tiny-invariant.js:12:11)
at router.ts:1014:9
at Array.forEach (<anonymous>)
at recurseRoutes (router.ts:1009:14)
at router.ts:1023:11
at Array.forEach (<anonymous>)
at recurseRoutes (router.ts:1009:14)
at Router.<anonymous> (router.ts:1065:5)
at Router.update (router.ts:361:24)
at new Router (router.ts:292:10)
How do I correctly use dynamic routes?
1 Reply
absent-sapphire
absent-sapphireOP3y ago
i fixed it, if you have the same issue do the following: add your dynamic route as a child route to the parent:
issueBaseRoute.addChildren([issueRoute]);
issueBaseRoute.addChildren([issueRoute]);
Remove the child route from the root route:
const routeTree = rootRoute.addChildren([indexRoute, issueBaseRoute, issueRoute]);
const routeTree = rootRoute.addChildren([indexRoute, issueBaseRoute, issueRoute]);
const routeTree = rootRoute.addChildren([indexRoute, issueBaseRoute]);
const routeTree = rootRoute.addChildren([indexRoute, issueBaseRoute]);

Did you find this page helpful?