Next.js Layouts: Shared UI That Survives Navigation
Think of a Next.js Layout as a picture frame that stays put while you swap the pictures (Pages) inside. It defines shared UI like headers that persist across routes, preserving state.
WHY IT EXISTS: In web apps, certain UI elements like navigation bars and footers are consistent across many pages. Re-rendering these on every page change is inefficient and causes state loss, like resetting a user's scroll position or clearing input in a search bar. Layouts solve this by providing a file-system-based convention for persistent UI that wraps page content.
THE MENTAL MODEL: A Layout is like the shell of your application—the navigation bar, sidebar, and footer. When you navigate from /dashboard to /dashboard/settings, the "picture" inside the shell changes (the page content), but the shell itself remains mounted and unchanged. This means any state within the layout, like a search bar's text, persists.
HOW IT WORKS: You create a file named layout.js (or .tsx) in a folder within your app directory. This file must export a default React component that accepts a children prop. Next.js automatically renders this children prop, which will be a child layout or a page.js component. You can nest layouts; a layout in app/dashboard/layout.js will be wrapped by the root layout in app/layout.js.
WHEN TO USE IT: Use layouts for any UI that should be shared and persistent across a set of routes. This is ideal for root application shells with headers and footers, dashboard sidebars, and any section of the UI that shouldn't lose its state when the user navigates between child pages.
WHEN NOT TO USE IT: Avoid layouts when you need a component to re-render and reset its state on every navigation. For example, if you want to run a useEffect hook to log a page view or trigger an enter animation every time a user visits a route, use a template.js file instead. A template has the same signature as a layout but creates a new instance for its children on each navigation.
ONE CANONICAL EXAMPLE: A common setup is a root layout in app/layout.js that defines the <html> and <body> tags, a main header, and a footer. Then, in a route group like app/(dashboard)/layout.js, you might define a two-column layout with a persistent sidebar for dashboard navigation. The page content for /dashboard/analytics would then render inside this two-column structure, which itself is inside the root layout's structure.
Read the original → nextjs.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.