T
TanStack11mo ago
compatible-crimson

layout route component get all child routes and context

Is it possible to create this structure
settings/
route.tsx
account.tsx
company.tsx
settings/
route.tsx
account.tsx
company.tsx
use route.tsx as the layout but get all "child" routes and the context of them in the route.tsx layout i want to loop over the children to create a navigation menu and get the context of those child components to create the label
export const Route = createFileRoute("/_app/settings/account")({
context: () => ({
getTitle: () => "Account",
}),
component: AccountSettings,
})
export const Route = createFileRoute("/_app/settings/account")({
context: () => ({
getTitle: () => "Account",
}),
component: AccountSettings,
})
4 Replies
compatible-crimson
compatible-crimsonOP11mo ago
Tried this but cant use the useRouteContext if it isnt matched
function SettingsLayout() {
const router = useRouter()
console.log(router.flatRoutes.map((route) => route.path))
const children: RouteType[] =
router.flatRoutes.find((route) => route.path === "settings")?.children ?? []

console.log(children.filter((route) => route.path !== "/"))

// const match = useRouteContext({ from: "/_app/settings/" })
// console.log(match)

// console.log(router.state.location)
return (
<div className="container max-w-2xl space-y-6">
<div className="flex flex-col justify-between space-y-2">
<h2 className="text-3xl font-bold tracking-tight">Settings</h2>
</div>
{children.map((route) => {
const context = route.useRouteContext()
console.log(context)
return (context.getTitle())
})}
<Outlet />
</div>
)
}
function SettingsLayout() {
const router = useRouter()
console.log(router.flatRoutes.map((route) => route.path))
const children: RouteType[] =
router.flatRoutes.find((route) => route.path === "settings")?.children ?? []

console.log(children.filter((route) => route.path !== "/"))

// const match = useRouteContext({ from: "/_app/settings/" })
// console.log(match)

// console.log(router.state.location)
return (
<div className="container max-w-2xl space-y-6">
<div className="flex flex-col justify-between space-y-2">
<h2 className="text-3xl font-bold tracking-tight">Settings</h2>
</div>
{children.map((route) => {
const context = route.useRouteContext()
console.log(context)
return (context.getTitle())
})}
<Outlet />
</div>
)
}
this seems to work but i get an type error on this
{children.map(({ path, options }) => {
const title = options.context?.()?.getTitle?.() ?? ""
// console.log(route.options.context()?.getTitle?.())
// // const context = route.useRouteContext()
// // console.log(context)
return (
<li key={path}>
<Link to={path}>{title}</Link>
</li>
)
})}
{children.map(({ path, options }) => {
const title = options.context?.()?.getTitle?.() ?? ""
// console.log(route.options.context()?.getTitle?.())
// // const context = route.useRouteContext()
// // console.log(context)
return (
<li key={path}>
<Link to={path}>{title}</Link>
</li>
)
})}
Expected 1 arguments, but got 0.ts(2554)
route.d.ts(65, 43): An argument for 'ctx' was not provided.
⚠ Error(TS2554) |
Expected 1 arguments, but got 0.
(property) context?: ((ctx: RouteContextOptions<AnyRoute, Record<never, string>, AnyContext, {}>) => any) | undefined
Expected 1 arguments, but got 0.ts(2554)
route.d.ts(65, 43): An argument for 'ctx' was not provided.
⚠ Error(TS2554) |
Expected 1 arguments, but got 0.
(property) context?: ((ctx: RouteContextOptions<AnyRoute, Record<never, string>, AnyContext, {}>) => any) | undefined
rare-sapphire
rare-sapphire11mo ago
TanStack | High Quality Open-Source Software for Web Developers
Headless, type-safe, powerful utilities for complex workflows like Data Management, Data Visualization, Charts, Tables, and UI Components.
From An unknown user
From An unknown user
compatible-crimson
compatible-crimsonOP11mo ago
Yes i did, this only returns direct child matches, i want to render all possible children of that layout. so the settings layout could have /settings/account and /settings/company right now i fixed it with
function SettingsLayout() {
const router = useRouter()

const children: RouteType[] = (
router.flatRoutes.find((route) => route.path === "settings")?.children ?? []
).filter((route: RouteType) => route.path !== "/")

return (
<div className="container max-w-2xl space-y-6">
<div className="flex flex-col justify-between space-y-4 border-b pb-4">
<h2 className="text-3xl font-bold tracking-tight">Settings</h2>
<nav className="flex items-center space-x-4 lg:space-x-6">
{children.map((child) => (
<Link
key={child.id}
to={child.to}
className="[&:not([data-status])]:text-muted-foreground hover:text-primary text-sm font-medium transition-colors"
>
{(child.options.context as () => RouteContext)().getTitle()}
</Link>
))}
</nav>
</div>
<Outlet />
</div>
)
}
function SettingsLayout() {
const router = useRouter()

const children: RouteType[] = (
router.flatRoutes.find((route) => route.path === "settings")?.children ?? []
).filter((route: RouteType) => route.path !== "/")

return (
<div className="container max-w-2xl space-y-6">
<div className="flex flex-col justify-between space-y-4 border-b pb-4">
<h2 className="text-3xl font-bold tracking-tight">Settings</h2>
<nav className="flex items-center space-x-4 lg:space-x-6">
{children.map((child) => (
<Link
key={child.id}
to={child.to}
className="[&:not([data-status])]:text-muted-foreground hover:text-primary text-sm font-medium transition-colors"
>
{(child.options.context as () => RouteContext)().getTitle()}
</Link>
))}
</nav>
</div>
<Outlet />
</div>
)
}
this does feel a bit hacky though.
rare-sapphire
rare-sapphire11mo ago
router.routesById would be less hacky?

Did you find this page helpful?