Next.js layouts wrap pages with persistent user interface elements such as headers, navigation bars, and sidebars. When a user moves between child routes, the shared layout stays mounted, keeps its state, and avoids unnecessary re-renders.
You define a layout by exporting a default React component that accepts a children prop inside a layout.tsx file.
Every App Router project needs a root layout at app/layout.tsx. It is the only layout file allowed to render the global <html> and <body> elements.
// app/layout.tsx
import './globals.css';
import Navbar from '@/components/Navbar';
import Footer from '@/components/Footer';
export const metadata = {
title: 'Developer Portal',
description: 'Documentation and workspace tools built with Next.js.',
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className="flex flex-col min-h-screen bg-gray-50">
<Navbar />
<main className="flex-1 max-w-6xl mx-auto w-full p-6">{children}</main>
<Footer />
</body>
</html>
);
}
Place another layout.tsx inside a subfolder like app/dashboard/ to wrap only routes under /dashboard. Next.js nests child layouts inside parent layouts automatically.
// app/dashboard/layout.tsx
import DashboardSidebar from '@/components/DashboardSidebar';
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div className="flex gap-6">
<DashboardSidebar />
<section className="flex-1 bg-white p-6 rounded-lg border">
{children}
</section>
</div>
);
}
template.tsx)While layout.tsx keeps component state across route changes, template.tsx creates a fresh instance on every navigation. Choose layout.tsx for persistent sidebars and scroll positions. Choose template.tsx when you need enter animations or per-page state resets.
<html> or <body> in nested layouts: Only app/layout.tsx may render <html> and <body>; nested layouts should return a container like <div> or <section>.layout.tsx re-runs on child navigation: Layouts do not re-mount when navigating between sibling pages, so do not put per-page analytics calls inside a layout useEffect.children; use React Context or URL search params when needed.Yes, layout.tsx is a Server Component by default, so you can make it async and fetch shared navigation or user data directly.
app/layout.tsx required in App Router?Next.js does not supply an implicit HTML wrapper, so app/layout.tsx defines the root document shell for all routes.
template.tsx instead of layout.tsx?Use template.tsx when switching between sibling pages must reset local React state or replay a CSS transition.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With