T
TanStack2y ago
other-emerald

Main Route in Outlet

Hello I am trying to figure out how to achieve something that should be simple but maybe I am making it more complicated than it actually is my "main" page is in a "dashboard" folder. The Route.tsx file is the file which is protected by auth and it has the Outlet that will render all the other pages of the dashboard. The problem is that the "route" is actually empty so if I go to "/dashboard" is empty while if I go to "/dashboard/beni-assicurati" it has the content of the Outlet, and I want "/dashboard/beni-assicuratI" to be the first page that the user see. The problem is that if I do a redirect in Route.tsx to "/dashboard/beni-assicurati" the app crashes as I think I am creating a loop.
export const Route = new FileRoute("/dashboard").createRoute({
beforeLoad: ({ context }) => {
const ctx = context as typeof store;
const { data } = ctx.getState().app.user;
if (!data) {
throw redirect({
to: "/login",
search: {
redirect: location.href,
},
});
}
},

// IF I DO ANOTHER REDIRECT HERE I CREATE A LOOP AND THE WEBSITE CRASH

component: Dashboard,
});

export default function Dashboard() {
return (
// SHOULD THIS BE A _layout?
<Box className="main">
<Header />
<HStack>
<Sidebar />
<Box
className="main-content"
px={48}
py={56}
h="full"
alignSelf="flex-start"
>
<Outlet />
</Box>
</HStack>
</Box>
);
}
export const Route = new FileRoute("/dashboard").createRoute({
beforeLoad: ({ context }) => {
const ctx = context as typeof store;
const { data } = ctx.getState().app.user;
if (!data) {
throw redirect({
to: "/login",
search: {
redirect: location.href,
},
});
}
},

// IF I DO ANOTHER REDIRECT HERE I CREATE A LOOP AND THE WEBSITE CRASH

component: Dashboard,
});

export default function Dashboard() {
return (
// SHOULD THIS BE A _layout?
<Box className="main">
<Header />
<HStack>
<Sidebar />
<Box
className="main-content"
px={48}
py={56}
h="full"
alignSelf="flex-start"
>
<Outlet />
</Box>
</HStack>
</Box>
);
}
Is there a better pattern that can I use?
No description
3 Replies
conscious-sapphire
conscious-sapphire2y ago
Yes, you can't add a second redirect in the src/routes/dashboard/route.tsx file, because this route configuration will be invoked on ALL routes nested under this dashboard path. Because of this, even if you visit /dashboard/beni-assicurati it still invokes the beforeLoad function defined in the route configuration for dashboard (src/routes/dashboard/route.tsx). Have you considered adding a src/routes/dashboard/index.component.tsx which contains this.
export const component = () => <Navigate to='/dashboard/beni-assicurati' />
export const component = () => <Navigate to='/dashboard/beni-assicurati' />
As such, if a user visits /dashboard it'll first check the auth status and if required throw a redirect. If not, it resolves to the index page of /dashboards that'll then navigate the user to /dashboard/beni-assicurati. You could also, throw a replace on the Navigate component to prevent pressing back to the index route of the dashboard path.
other-emerald
other-emeraldOP2y ago
thanks a lot @Sean Cassiere ! Another quick question, sorry to bother you. I am trying to create a breadcrumb component. Given the structure from the image, why router.state.matches doesn't have an intermediate route? I was expecting. Sorry for the many questions I am getting used to Tanstack Router!
const breadcrumbs = router.state.matches;

-> [
{
"id": "__root__",
"routeId": "__root__",
"params": {
"**": "index/nuovo-cespite"
},
"pathname": "/",
},
{
"id": "/dashboard",
"routeId": "/dashboard",
"params": {
"**": "index/nuovo-cespite"
},
"pathname": "/dashboard",
,,,,
},
** // I WAS EXPECTING A ROUTE HERE "/dashboard/beni-assicurati"**
{
"id": "/dashboard/beni-assicurati/nuovo-cespite",
"routeId": "/dashboard/beni-assicurati/nuovo-cespite",
"params": {},
"pathname": "/dashboard/beni-assicurati/nuovo-cespite",
,,,,
}
]
const breadcrumbs = router.state.matches;

-> [
{
"id": "__root__",
"routeId": "__root__",
"params": {
"**": "index/nuovo-cespite"
},
"pathname": "/",
},
{
"id": "/dashboard",
"routeId": "/dashboard",
"params": {
"**": "index/nuovo-cespite"
},
"pathname": "/dashboard",
,,,,
},
** // I WAS EXPECTING A ROUTE HERE "/dashboard/beni-assicurati"**
{
"id": "/dashboard/beni-assicurati/nuovo-cespite",
"routeId": "/dashboard/beni-assicurati/nuovo-cespite",
"params": {},
"pathname": "/dashboard/beni-assicurati/nuovo-cespite",
,,,,
}
]
No description
conscious-sapphire
conscious-sapphire2y ago
I believe router.state.matches should return the hierarchy you are talking about. What is shown in the Router devtools for the matches? If the devtools are showing what is expected, could you reproduce it in a Stackblitz repo? It may just be a bug, so a reproducible sandbox will be helpful if an issue needs to be logged.

Did you find this page helpful?