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.








Thanks for sharing the idea.
However, the problem is, since the root component is using the hook
useLocation(), whenever the route changes, the whole application is re-rendered.