This content originally appeared on DEV Community and was authored by حذيفة
if you read this issue discussion on GitHub :
Custom Layout for Specific Routes in tanstack/router #1102
you’ll see that this is a big issue. Surprisingly, such a basic feature is not available in a large project like TanStack Router. Even though the issue is marked as resolved, that’s not really the case. I tried all the suggested solutions, but none of them worked for me. I also went through the documentation and found that there’s still no official support for this. However, I managed to solve it with a workaround.
![]() |
![]() |
![]() |
---|
The Scenario :
I am working on a [react + vite + Tanstack Router] Project for a clothes store,
I have two type of pages :
- regular pages : Home Page, Product Page, Collection Page, Search Page, Checkout Page.
- Dashboard Pages : Statistics Page, CRUD Product Page, Handling Orders Page,
The regular pages anyone can navigate them, and they have layout of <NavBar />
& <Footer />
The Dashboard pages for the admin, and they have layout of <SideBar />
The routing type implemented here is the File-Based Routing
.
The Problem :
when I set a custom layout for the dashboard, it wrapped by the layout of the regular pages.
The /src/routes
directory Hierarchy :
\routes
| checkout.jsx
| collection.jsx
| index.jsx
| product.jsx
| search.jsx
| __root.jsx
|
\---dashboard
| index.jsx
| route.jsx
|
\---products
index.jsx
the src/routes/__root.jsx
file :
import { createRootRoute, Outlet } from "@tanstack/react-router";
import Navbar from "@/components/Navbar";
import Footer from "@/components/Footer";
import NotFoundPage from "@/components/NotFoundPage";
export const Route = createRootRoute({
notFoundComponent: () => <NotFoundPage />,
component: () => {
return (
<div>
<Navbar />
<Outlet />
<Footer />
</div>
);
},
});
the /src/routes/dashboard/route.jsx
file :
import { Outlet, Link, createFileRoute } from "@tanstack/react-router";
import SideBar from "@/componenets/SideBar";
export const Route = createFileRoute("/dashboard")({
component: () => {
return (
<div className="flex h-screen bg-gray-50">
<SideBar />
<main className="flex-1 p-6 overflow-y-auto">
<Outlet />
</main>
</div>
);
},
});
so when i browse /Dashboard/products
The Given Result :
<NavBar />
<div className="flex h-screen bg-gray-50">
<SideBar />
<main className="flex-1 p-6 overflow-y-auto">
<Outlet />
</main>
</div>
<Footer/>
The Wanted Result :
<div className="flex h-screen bg-gray-50">
<SideBar />
<main className="flex-1 p-6 overflow-y-auto">
<Outlet />
</main>
</div>
So How can you set a custom Layout for Dashboard Sub Pages.
The Solution :
The trick is to use conditional rendering: if the route starts with /dashboard/, it won’t be wrapped by any component.
the src/routes/__root.jsx
file again, but with Conditional Rendering :
import React, { useState} from "react";
import { createRootRoute, Outlet, useLocation } from "@tanstack/react-router";
import Navbar from "../components/Navbar";
import Footer from "../components/Footer";
import NotFoundPage from "../components/NotFoundPage";
export const Route = createRootRoute({
notFoundComponent: () => <NotFoundPage />,
component: RootComponent,
});
function RootComponent() {
const location = useLocation();
const pathname = location.pathname;
if (pathname.startsWith("/dashboard")) {
return <DashboardRoute />;
} else {
return <RegularRoute />;
}
}
function DashboardRoute() {
return (
<>
<Outlet />
</>
);
}
function RegularRoute() {
return (
<Navbar />
<Outlet />
<Footer />
);
}
I hope this is helpful to everyone.
leave a love & a comment so more people can reach it.
This content originally appeared on DEV Community and was authored by حذيفة