T
TanStack•12mo ago
like-gold

Breaking parent layout inheritance

Hi everyone, I'm using file-based routing and have the following structure:
/_root.tsx // Uses HomeLayout component
/$lang/apps/index.tsx // Uses AppsList component, inherits HomeLayout from _root
/$lang/workspaces/index.tsx // Uses WorkspaceList component, inherits HomeLayout from _root
/_root.tsx // Uses HomeLayout component
/$lang/apps/index.tsx // Uses AppsList component, inherits HomeLayout from _root
/$lang/workspaces/index.tsx // Uses WorkspaceList component, inherits HomeLayout from _root
I want to create a new route /$lang/apps/$category/pages.tsx This needs a new layout, not inherit the HomeLayout. I tried adding /$lang/apps/$category/_index_.tsx (also _route_.tsx with <MainLayout> component (with outlet of course) but no luck. what am I missing? 🙂 Every sub-page of $category should be using the MainLayout
23 Replies
vicious-gold
vicious-gold•12mo ago
you cannot not use the root layout so in this caes, you should move HomeLayout into a separate layout route
like-gold
like-goldOP•12mo ago
So root layouts will always be inherited by children, no matter if adding _ suffix?
vicious-gold
vicious-gold•12mo ago
yes. but you can have a layout route directly after root, and you can opt out that
like-gold
like-goldOP•12mo ago
Hmm ok. Let me try that. There's a little bit of "complication" though it might not be, that no one should actually end up on the root page xD
import { QueryClient } from '@tanstack/react-query';
import { createRootRouteWithContext, redirect } from '@tanstack/react-router';
import { getCurrentSite } from 'src/entities/site/queries/useGetCurrentSite';
import { HomeLayout } from 'src/widgets/HomeLayout';

export const Route = createRootRouteWithContext<{
queryClient: QueryClient;
}>()({
beforeLoad: async ({ context: { queryClient }, location }) => {
const { languages } = await queryClient.ensureQueryData(getCurrentSite());

if (location.pathname === '/' || location.pathname === '/$lang') {
throw redirect({
to: `/${languages[0]}/apps`,
replace: true,
});
}
},
pendingMinMs: 0,
component: () => <HomeLayout />,
});
import { QueryClient } from '@tanstack/react-query';
import { createRootRouteWithContext, redirect } from '@tanstack/react-router';
import { getCurrentSite } from 'src/entities/site/queries/useGetCurrentSite';
import { HomeLayout } from 'src/widgets/HomeLayout';

export const Route = createRootRouteWithContext<{
queryClient: QueryClient;
}>()({
beforeLoad: async ({ context: { queryClient }, location }) => {
const { languages } = await queryClient.ensureQueryData(getCurrentSite());

if (location.pathname === '/' || location.pathname === '/$lang') {
throw redirect({
to: `/${languages[0]}/apps`,
replace: true,
});
}
},
pendingMinMs: 0,
component: () => <HomeLayout />,
});
I can use a root route without a component? @Manuel Schiller Or is there maybe a better way of doing that with tanstack router
vicious-gold
vicious-gold•12mo ago
yes you can remove the component from root it will the simply be an Outlet
like-gold
like-goldOP•12mo ago
Thanks. You've pushed me on the right track 🙂
vicious-gold
vicious-gold•12mo ago
i created an example for you
like-gold
like-goldOP•12mo ago
The _layout folder does confuse me a bit 🥲
vicious-gold
vicious-gold•12mo ago
you have to express which routes should be rendered inside that layout and which should not all inside will get the layout the other wont
like-gold
like-goldOP•12mo ago
So I could do something like _home and _main to define layouts?
vicious-gold
vicious-gold•12mo ago
you can name it whatever you like just prefix with _ so it is a pathless route (i.e. does not contribute to the url path)
like-gold
like-goldOP•12mo ago
Thank you @Manuel Schiller I think I got it working now 🙂 It's not the prettiest thing, compared to code based, but at least it's a proof of concept 🙂
No description
vicious-gold
vicious-gold•12mo ago
you could also consider flat routes instead of folders. then you won't need layout folders it would just be for example
_home.$lang.apps.workspaces.index.tsx
_home.$lang.apps.workspaces.index.tsx
you can also mix flat and folder scheme
vicious-gold
vicious-gold•12mo ago
and if you truly do not like that folder setup, you could configure the routing using https://tanstack.com/router/v1/docs/framework/react/guide/virtual-file-routes
Virtual File Routes | TanStack Router React Docs
We'd like to thank the Remix team for pioneering the concept of virtual file routes. We've taken inspiration from their work and adapted it to work with TanStack Router's existing file-based route-tree generation. Virtual file routes are a powerful concept that allows you to build a route tree programmatically using code that references real fi...
like-gold
like-goldOP•12mo ago
Thanks. I am gonna discuss with my team on monday I think. I really want to use tanstack more in our new project, but everyone has been so set on react-router for so long. I just need to show a proof of concept that the routing can be done in the same way. I have a feeling the file based routing like we have now is gonna put some of the team off. Code based probably looks like the easiest swap for my team, but then it's the issue of documentation 🥲
vicious-gold
vicious-gold•12mo ago
which issue?
like-gold
like-goldOP•12mo ago
The documentation is mostly written with file based in mind right. At least that's what the documentation says 🥲
vicious-gold
vicious-gold•12mo ago
yes that's true we recommend file based routing so have you been using react-router with file based routing?
like-gold
like-goldOP•12mo ago
No, I didn't set up the original routing but it looked something like this
<>
<Route path="/" element={<HomeLayout />}>
<Route index element={<HomePage />} />
<Route path=":lang" element={<HomePage />} />
<Route path=":lang/apps" element={<HomePage />} />
<Route path=":lang/workspaces" element={<WorkspaceList />} />
</Route>
<Route
path="/:lang/apps/:appUri/:category?"
element={<RootAppRouter />}
/>
<Route path="/:lang">
<Route path="apps" element={<MainPage />}>
<Route
path=":appUri/:category?/pages/:pageUri?"
element={<Pages />}
/>
<>
<Route path="/" element={<HomeLayout />}>
<Route index element={<HomePage />} />
<Route path=":lang" element={<HomePage />} />
<Route path=":lang/apps" element={<HomePage />} />
<Route path=":lang/workspaces" element={<WorkspaceList />} />
</Route>
<Route
path="/:lang/apps/:appUri/:category?"
element={<RootAppRouter />}
/>
<Route path="/:lang">
<Route path="apps" element={<MainPage />}>
<Route
path=":appUri/:category?/pages/:pageUri?"
element={<Pages />}
/>
Shortened of course MainPage being the MainLayout and the RootAppRouter just handling redirection
vicious-gold
vicious-gold•12mo ago
Decisions on Developer Experience | TanStack Router React Docs
When people first start using TanStack Router, they often have a lot of questions that revolve around the following themes: Why do I have to do things this way?
vicious-gold
vicious-gold•12mo ago
might help convincing
like-gold
like-goldOP•12mo ago
@Manuel Schiller I had a 30 minute presentation basically, and everyone loved it. They weren't 100% convinced of the file based routes, but that was mostly aesthetics and initial confusion as to why we needed a "branched" route tree. Thanks for your help, again. Hopefully we can get used to this way of routing. But I agree with what I've seen others have commented on issues similar to mine. It can get a bit confusing 🥲

Did you find this page helpful?