T
TanStack4w ago
quickest-silver

optional param with required param route question

I have this folder structure
a/
index.tsx
route.tsx
b/
index.tsx
route.tsx
$c/
index.tsx
route.tsx
$d.tsx

a/
index.tsx
route.tsx
b/
index.tsx
route.tsx
$c/
index.tsx
route.tsx
$d.tsx

a/route.tsx and b/route.tsx and $c/route.tsx are only having loader, that returns crumb into the context, something like that:
export const Route = createFileRoute(
"/a"
)({
loader: ({ context }) => ({ crumb: "A" }),
});
export const Route = createFileRoute(
"/a"
)({
loader: ({ context }) => ({ crumb: "A" }),
});
( I need this in order to create correct breadcrumbs.) My understanding was that index.tsx is the page to be rendered, and route.tsx - is kind of layout if needed, but optional. so in my mind, accessing /a/b/$c would effectively render the /a/b/$c/index.tsx into the browser. But accessing /a/b/$c gives an empty page... Tanstack Router devtools shows correct matches. The only thing slowly driving me crazy is that the page is empty... If I move the stuff from $c/index.tsx to $c/route.tsx, the /a/b/$c shows correct info, but then I would get the exact same page for /a/b/$c/$d as for /a/b/$c, because, I believe, route.tsx is used as layout... I think my question boils down to: "How to make nested pages with multiple parameters, like /a/b/$c/$d, and also be able to access in-between pages as well (/a/b/$c) ?"
8 Replies
fascinating-indigo
fascinating-indigo4w ago
did you return outlet in your route.tsx? if you dont render Outlet in $c/route.tsx... then the child routes ($c/index.tsx and $d.tsx) wont be rendered
quickest-silver
quickest-silverOP3w ago
I'm not really sure about that, I have a/route.tsx and a/b/route.tsx files, and both without Outlet, and content of these pages is content from the respective index.tsx files. But somehow this isn't working in case of dynamic params like $c / $d (?...) If I add Outlet to a/b/$c/route.tsx like this
export const Route = createFileRoute(
"/a/b/$c"
)({
loader: ({ params }) => ({ crumb: params.c }),
component: Outlet,
});
export const Route = createFileRoute(
"/a/b/$c"
)({
loader: ({ params }) => ({ crumb: params.c }),
component: Outlet,
});
Ii I add route.tsx, I can see that the /a/b/$c/route.tsx is rendered, but not the /a/b/$c/index.tsx Looks like it's because I've done some hacking for i18n routing with router'srewrite. If I remove it, the index.tsx renders as expected.
extended-salmon
extended-salmon3w ago
Just another tip, if you do not specify a component on your route, it uses Outlet by default
quickest-silver
quickest-silverOP3w ago
After re-checking, I actually found out that the issue has something to do with optional lang param in the very beginning. I thought it is not connected to this issue at first, so I didn't included it in my question... My actual folders are more like this
{-$lang}/
a/
index.tsx
route.tsx
b/
index.tsx
route.tsx
$c/
index.tsx
route.tsx
$d.tsx
{-$lang}/
a/
index.tsx
route.tsx
b/
index.tsx
route.tsx
$c/
index.tsx
route.tsx
$d.tsx
Without the rewrite, page {-$lang}/a/b/$c/ correctly shows, but only if there is no lang (pathname like /a/b/123). If the lang is explicitly set like "/en/a/b/123", the page renders only the template - route.tsx and ignores index.tsx...
extended-salmon
extended-salmon3w ago
is the rewrite meant to go to a default language if there isnt one in the url?
foreign-sapphire
foreign-sapphire3w ago
Hey. I think I have the same issue. I've created a reproduction: https://stackblitz.com/edit/tanstack-router-1vx3xnsd?file=src%2Froutes%2Findex.tsx
Matheus Landuci
StackBlitz
Router Optional Param + Non optional param not found - StackBlitz
Run official live example code for Router Basic File Based, created by Tanstack on StackBlitz
foreign-sapphire
foreign-sapphire3w ago
It only happens when we have a required param and a optional param (example: {-$slug}/posts/$id}
quickest-silver
quickest-silverOP3w ago
Exactly! the index.tsx can only be accessed if the optional parameter is not defined. Thank you for the reproduction. Yes, I do it for when accessing a page with _splat say, /foo/bar with no explicitly set route and with no language specified, to get the entry from db with id "foo/bar", to prevent foo to be interpreted as a language and quietly re-route it to /<default-lang>/foo/bar. Found this PR that should resolve this issue: https://github.com/TanStack/router/pull/5176 Looks like the person who reviewing it is now busy with other issues, but it was a month ago. Commented there.

Did you find this page helpful?