T
TanStack•10mo ago
fair-rose

Check if user is in Index Route

Is it possible to check if the user is in the index route? I am trying to use shadcn tabs as links, and need to set values. This is easy enough for the child routes as I can use useLocation to get the pathname, then run pathname.split('/').pop() to get the last value of the route. However this doesn't work for the index route as pathname doesn't have a trailing slash. I found a weird workaround like this
const pathValue = useLocation({
select: (location) => location.pathname.split('/')[3] || '',
});
const pathValue = useLocation({
select: (location) => location.pathname.split('/')[3] || '',
});
But this requires knowing exactly how long the path should be. Feels like there is an easier method that i might just be blanking on. Can provide more context if needed, thanks!
15 Replies
fair-rose
fair-roseOP•10mo ago
sidenote: I could use the link path as the value and then just get the location. However since the link is set like this for typesafety
<Link
to: '/trips/$tripId/accommodations',
params: { tripId },
>
Accommodations
</Link>
<Link
to: '/trips/$tripId/accommodations',
params: { tripId },
>
Accommodations
</Link>
I don't think there is any way of getting the computed value?
afraid-scarlet
afraid-scarlet•10mo ago
can you show a complete example please where you ultimately need this value in the shadcn tabs?
fair-rose
fair-roseOP•10mo ago
i have link options laid out like this
const options = [
linkOptions({
to: '/trips/$tripId',
label: 'Full Schedule',
params: { tripId },
replace: true,
value: '',
}),
linkOptions({
to: '/trips/$tripId/accommodations',
label: 'Accommodations',
params: { tripId },
replace: true,
value: 'accommodations',
}),
linkOptions({
to: '/trips/$tripId/transportation',
label: 'Transportation',
params: { tripId },
replace: true,
value: 'transportation',
}),
linkOptions({
to: '/trips/$tripId/activities',
label: 'Activities',
params: { tripId },
replace: true,
value: 'activities',
}),
];
const options = [
linkOptions({
to: '/trips/$tripId',
label: 'Full Schedule',
params: { tripId },
replace: true,
value: '',
}),
linkOptions({
to: '/trips/$tripId/accommodations',
label: 'Accommodations',
params: { tripId },
replace: true,
value: 'accommodations',
}),
linkOptions({
to: '/trips/$tripId/transportation',
label: 'Transportation',
params: { tripId },
replace: true,
value: 'transportation',
}),
linkOptions({
to: '/trips/$tripId/activities',
label: 'Activities',
params: { tripId },
replace: true,
value: 'activities',
}),
];
then i'm creating my tabs like so
<Tabs value={pathValue} className="mb-6">
<TabsList>
{options.map((option) => {
return (
<TabsTrigger
asChild
value={option.value}
key={option.to}
className="transition-colors hover:bg-background/20"
>
<Link {...option} resetScroll={false}>
{option.label}
</Link>
</TabsTrigger>
);
})}
</TabsList>
</Tabs>
<Tabs value={pathValue} className="mb-6">
<TabsList>
{options.map((option) => {
return (
<TabsTrigger
asChild
value={option.value}
key={option.to}
className="transition-colors hover:bg-background/20"
>
<Link {...option} resetScroll={false}>
{option.label}
</Link>
</TabsTrigger>
);
})}
</TabsList>
</Tabs>
and i'm calculating the value of the path based on the route
const pathValue = useLocation({
select: (location) => location.pathname.split('/')[3] || '',
});
const pathValue = useLocation({
select: (location) => location.pathname.split('/')[3] || '',
});
afraid-scarlet
afraid-scarlet•10mo ago
what is meant by value here for each tab? a full example would really be helpful
fair-rose
fair-roseOP•10mo ago
each TabsTrigger has a value, and then based off the value of the outer Tabs component, the corresponding TabsTrigger is styled, it may honestly be the case where i should just use links and style them myself with the activeProps @Manuel Schiller
afraid-scarlet
afraid-scarlet•10mo ago
sounds a bit like it, yes.
fair-rose
fair-roseOP•10mo ago
realized I might be overcomplicating things for myself 😂
afraid-scarlet
afraid-scarlet•10mo ago
otherwise, if you don't want to go that route, I would suggest using useMatch instead of useLocation
fair-rose
fair-roseOP•10mo ago
shouldn't the pathname from useLocation() end with a trailing slash if i'm in an index route?
afraid-scarlet
afraid-scarlet•10mo ago
depends on whether you enabled trailing slashes it's a router option that is off by default
fair-rose
fair-roseOP•10mo ago
Oh cool I didn't realize that, i'll play around with that and see if i can get it to work, otherwise may just go with Links. Thanks for the help!
afraid-scarlet
afraid-scarlet•10mo ago
look into this as well
fair-rose
fair-roseOP•10mo ago
useMatch didn't seem to work. It always gives me the parent route when using Route.useMatch. I may have figured something out with useChildMatches though. When calling both useLocation and useChildMatches in the parent route, The useLocation() pathname is "/trips/30" but the first useChildMatches() entry has a pathname "/trips/30/" with the trailing slash is that intended?
afraid-scarlet
afraid-scarlet•10mo ago
yes because pathname from useLocation reflects the actual url in the address bar and that has or has not the trailing slash, depending on the setting
fair-rose
fair-roseOP•10mo ago
okay perfect thanks for the info

Did you find this page helpful?