Layouts
A layout.tsx wraps a segment and all pages beneath it, and it stays mounted across navigation.
app/layout.tsx exports a component receiving { children }A layout is shared UI that wraps the pages in its segment. The root layout at app/layout.tsx is required and must render the <html> and <body> tags. Nested layouts wrap only their part of the tree.
Layouts receive a children prop — the page or nested layout to render inside them. Crucially, layouts preserve state and do not re-render when you navigate between sibling pages.
Example
// app/layout.tsx (root layout — required)
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<nav>My Site</nav>
{children}
</body>
</html>
);
}When to use it
- A dashboard wraps all its pages in a sidebar layout defined once in app/dashboard/layout.tsx.
- A root layout.tsx adds a global navigation bar and footer that remain mounted during client-side navigation.
- An authenticated section adds a token check in its layout so every nested page is protected automatically.
More examples
Root layout with HTML shell
The root layout must include html and body tags and wraps every page in the app.
// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<header>Site Nav</header>
{children}
<footer>Site Footer</footer>
</body>
</html>
);
}Nested segment layout
This layout applies only to routes under /dashboard and stays mounted when navigating between dashboard pages.
// app/dashboard/layout.tsx
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
<div style={{ display: 'flex' }}>
<aside style={{ width: 200 }}>Sidebar</aside>
<main style={{ flex: 1 }}>{children}</main>
</div>
);
}Layout with async data
Layouts can be async Server Components, allowing them to fetch session data before rendering.
// app/dashboard/layout.tsx
import { getCurrentUser } from '@/lib/auth';
export default async function DashboardLayout({ children }: { children: React.ReactNode }) {
const user = await getCurrentUser();
return (
<div>
<p>Welcome, {user.name}</p>
{children}
</div>
);
}
Discussion