T
TanStack•16mo ago
conscious-sapphire

Implementing something similar to Processing Accumulated Route Context for just one app

I'd like to implement something similar to https://tanstack.com/router/latest/docs/framework/react/guide/router-context using useMatches the key difference being that I don't want accumulation I just want to specify the name of the app in the parent route and have that propagate to all children Currently however using
const matchWithTitle = useMatches().reverse().find((d) => d.routeContext.getTitle);

const title = matchWithTitle?.routeContext.getTitle() || "Main";
const matchWithTitle = useMatches().reverse().find((d) => d.routeContext.getTitle);

const title = matchWithTitle?.routeContext.getTitle() || "Main";
isn't working for the children routes, its getting something like
[
{
"id": "__root__",
"routeId": "__root__",
"params": {},
"pathname": "/",
"updatedAt": 1716850049090,
"search": {},
"status": "success",
"isFetching": false,
"loadPromise": {
"status": "resolved"
},
"routeContext": {},
...
},
{
"id": "/training/locations/mainspace",
"routeId": "/training/locations/mainspace",
"params": {},
"pathname": "/training/locations/mainspace",
"updatedAt": 1716850048592,
"search": {},
"status": "success",
"isFetching": false,
"loadPromise": {
"status": "resolved"
},
"routeContext": {},
...
}
]
[
{
"id": "__root__",
"routeId": "__root__",
"params": {},
"pathname": "/",
"updatedAt": 1716850049090,
"search": {},
"status": "success",
"isFetching": false,
"loadPromise": {
"status": "resolved"
},
"routeContext": {},
...
},
{
"id": "/training/locations/mainspace",
"routeId": "/training/locations/mainspace",
"params": {},
"pathname": "/training/locations/mainspace",
"updatedAt": 1716850048592,
"search": {},
"status": "success",
"isFetching": false,
"loadPromise": {
"status": "resolved"
},
"routeContext": {},
...
}
]
and /training isn't included in that (which is where the getTitle is defined)
Router Context | TanStack Router React Docs
TanStack Router's router context is a very powerful tool that can be used for dependency injection among many other things. Aptly named, the router context is passed through the router and down through each matching route. At each route in the hierarchy, the context can be modified or added to. Here's a few ways you might use the router context...
25 Replies
adverse-sapphire
adverse-sapphire•16mo ago
here is what I'm doing:
const pageTitle = useRouterState({
select: (state) =>
findLast(state.matches, (match) => Boolean(match.context.pageTitle))?.context.pageTitle,
})
const pageTitle = useRouterState({
select: (state) =>
findLast(state.matches, (match) => Boolean(match.context.pageTitle))?.context.pageTitle,
})
conscious-sapphire
conscious-sapphireOP•16mo ago
if I'm on /training/locations/mainspace this doesn't include /training unfortunately. it still has the same list of matches as shown in the first message
adverse-sapphire
adverse-sapphire•16mo ago
would need to see a minimal reproduction by forking one of our examples please. if there is a route / shared layout for /training, it should match.
conscious-sapphire
conscious-sapphireOP•16mo ago
ah looking at the routeTree.gen.ts file I can see that the getParentRoute isn't picking the actual parent it's taking
const TrainingLocationsMainspaceRoute = TrainingLocationsMainspaceImport.update(
{
path: '/training/locations/mainspace',
getParentRoute: () => rootRoute,
} as any,
)
const TrainingLocationsMainspaceRoute = TrainingLocationsMainspaceImport.update(
{
path: '/training/locations/mainspace',
getParentRoute: () => rootRoute,
} as any,
)
(root) which isn't correct @TkDodo 🔮 is this possible to change the behaviour of?
like-gold
like-gold•16mo ago
which parent should it take instead? please provide a minimal complete example
conscious-sapphire
conscious-sapphireOP•16mo ago
should parent not be the locations path? is this not normal behaviour for it to be the rootRoute?
like-gold
like-gold•16mo ago
does the locations route exist? if you did not define it, router won't create it for you
conscious-sapphire
conscious-sapphireOP•16mo ago
oh so if i add locations as a route that will work? it still seems to be using the root route even if the /locations/index.tsx file exists
like-gold
like-gold•16mo ago
create a route that is not the index
conscious-sapphire
conscious-sapphireOP•16mo ago
in /locations?
like-gold
like-gold•16mo ago
probably, but without seeing a complete example I cannot say for sure
conscious-sapphire
conscious-sapphireOP•16mo ago
well im confused as to what the default behaviour is here i mean the behaviour looks default here https://stackblitz.com/edit/tanstack-router-rmbven?file=src/main.tsx&preset=node actually that stackblitz link doesnt work but idk whats happening its not picking up file changes in a subdirectory in a new fork
conscious-sapphire
conscious-sapphireOP•16mo ago
StackBlitz
Router Quickstart File Based Example (forked) - StackBlitz
Run official live example code for Router Quickstart File Based, created by Tanstack on StackBlitz
conscious-sapphire
conscious-sapphireOP•16mo ago
so id imagine that the help route should have its parent as test/
like-gold
like-gold•16mo ago
StackBlitz
Router Quickstart File Based Example (forked) - StackBlitz
Run official live example code for Router Quickstart File Based, created by Tanstack on StackBlitz
like-gold
like-gold•16mo ago
i added a separate test.tsx route
conscious-sapphire
conscious-sapphireOP•16mo ago
oh ic so is that the recommened way to do this then?
like-gold
like-gold•16mo ago
if you need the parent route to exist for whatever reason, you need to create it. there is no other way
conscious-sapphire
conscious-sapphireOP•16mo ago
ideally though it would 404 so you couldnt access it and it probably should be removed from types
like-gold
like-gold•16mo ago
then you should not add it 😄 i did not fully understand the matching problem above
conscious-sapphire
conscious-sapphireOP•16mo ago
id just like to be able to define the title of the app based on the first part of the path of the url e.g. /training is called the "Training" app and all of its children should have the getTitle method return "Training" but if a child overwrites this then it can be called something else
conscious-sapphire
conscious-sapphireOP•16mo ago
but for some reason even thought the /training route exists its not picking up /training as the parent
No description
conscious-sapphire
conscious-sapphireOP•16mo ago
its saying its / I do find the duplication a bit annoying
like-gold
like-gold•16mo ago
I would put data like this into staticData of the routes instead of using the path somehow
conscious-sapphire
conscious-sapphireOP•16mo ago
import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/training")({
beforeLoad: () => ({ title: "Training" }),
});
import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/training")({
beforeLoad: () => ({ title: "Training" }),
});
this is what i have in the training.tsx file ideally id want this in training/index.tsx and to have it work the same way or something similar though then again if this doesnt show up in useMatches (cause its not resolving without the training.tsx file) then its not gonna be particularly useful having this not propagate fully up the stack has already bitten us because it didnt work for authed routes :(

Did you find this page helpful?