Next.js App Router: Layouts vs Templates Explained
Most Next.js routing problems stem from choosing the wrong wrapper component. Learn exactly when to use layouts versus templates, and why the distinction matters for state persistence and performance.
Next.js App Router: Layouts vs Templates Explained
Most Next.js routing problems stem from misunderstanding the difference between layouts and templates. Developers reach for layouts when they need templates, or vice versa, and end up with broken state persistence or unnecessary re-renders. The failure mode here is subtle but expensive: animations that restart on navigation, form inputs that clear unexpectedly, or context providers that reset when they shouldn't.
The distinction between these two patterns is fundamental to building performant Next.js applications. Layouts persist across route changes and maintain their state. Templates create fresh instances on every navigation and reset their state. This seemingly small difference has massive implications for how your application behaves in production.
Understanding Layouts: Persistent UI Shells That Maintain State
Layouts represent the persistent shell of your application. When developers navigate between routes that share a layout, Next.js reuses the same component instance. The component doesn't unmount and remount—it stays alive, preserving its state, effects, and even scroll position.
This behavior makes layouts ideal for navigation bars, sidebars, and any UI element that should remain stable as users move through your application. The layout component renders once, then persists as child routes change beneath it.
The technical implementation relies on React's component reconciliation. Next.js wraps child routes in the layout component and only updates the children when the route changes. The layout component itself receives new props but doesn't remount unless the layout file itself changes in the route hierarchy.

Building Your First Layout Component
A layout component in the App Router follows a specific pattern. The component must accept a children prop and return JSX that wraps those children. This contract allows Next.js to inject the appropriate page content at runtime.
Here's a production-ready layout that demonstrates state persistence:
// app/dashboard/layout.tsx
'use client'
import { useState } from 'react'
import { Navigation } from '@/components/Navigation'
import { Sidebar } from '@/components/Sidebar'
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
const [sidebarOpen, setSidebarOpen] = useState(true)
const [notificationCount, setNotificationCount] = useState(3)
return (
<div className="dashboard-container">
<Navigation
onToggleSidebar={() => setSidebarOpen(!sidebarOpen)}
notificationCount={notificationCount}
/>
<div className="dashboard-content">
{sidebarOpen && (
<Sidebar
onNotificationRead={() => setNotificationCount(prev => prev - 1)}
/>
)}
<main>{children}</main>
</div>
</div>
)
}This layout maintains sidebarOpen and notificationCount state across all routes under /dashboard. When developers navigate from /dashboard/analytics to /dashboard/settings, the sidebar remains in its current state. The notification count doesn't reset. This pattern eliminates jarring UI resets and creates a seamless navigation experience.
The key insight here is that state persistence happens automatically. Developers don't need to hoist state to a higher level or use global state management. The layout component's lifecycle matches the route segment's lifecycle, not individual page transitions.
Understanding Templates: Fresh Instances on Every Navigation
Templates serve a different purpose. While layouts persist, templates reset. Every navigation that renders a template creates a new component instance from scratch. The previous instance unmounts completely, running all cleanup effects and clearing all state.
This reset behavior makes templates essential for scenarios where developers need guaranteed fresh state. Exit animations that should play on every navigation require templates. Analytics tracking that fires on each page view requires templates. Form components that must reset between routes require templates.
The implementation difference is minimal but the runtime behavior is fundamentally different. Templates use the same props interface as layouts but trigger React's unmount and mount cycle on every route change.
Layouts vs Templates: Side-by-Side Comparison
The functional difference between layouts and templates manifests in three critical areas: component lifecycle, state persistence, and performance characteristics.
When a user navigates between two routes that share a layout, React maintains the same component instance. The layout's state persists, effects don't re-run (unless dependencies change), and refs remain valid. This means a search input in your layout keeps its value, an animation playing in your sidebar continues uninterrupted, and WebSocket connections stay open.
When the same navigation involves a template, React unmounts the old instance and mounts a new one. State resets to initial values, all effects run their cleanup functions and re-initialize, and refs get new values. A search input in your template clears, an animation restarts from the beginning, and WebSocket connections close and reopen.
The performance implications differ significantly. Layouts are more efficient for persistent UI because React avoids the mount/unmount cycle. Templates incur the full cost of component initialization on every navigation but guarantee clean state and complete effect execution.

Practical Use Cases: When to Use Each Pattern
The choice between layouts and templates depends on your specific requirements. Most applications use layouts as the default pattern and reach for templates only when they need explicit state resets.
Use layouts for navigation shells, authentication wrappers, theme providers, and any UI that should feel stable across navigation. A dashboard with a persistent sidebar belongs in a layout. A header with a search bar that maintains its value between pages belongs in a layout. A shopping cart that stays visible across product pages belongs in a layout.
Use templates for pages with exit animations, analytics tracking requirements, or form components that must start fresh. An onboarding flow where each step animates out before the next animates in requires templates. A checkout process where form validation should reset between steps requires templates. A documentation site where page view tracking must fire on every navigation requires templates.
The distinction matters because the wrong choice creates bugs that only appear in production. A layout used where a template should be causes state to leak between routes. A template used where a layout should be causes unnecessary re-renders and poor performance.
Advanced Pattern: Nested Layouts with Templates
Complex applications often combine both patterns in a nested hierarchy. A root layout provides application-wide UI persistence while child templates handle route-specific reset requirements.
// app/checkout/layout.tsx
export default function CheckoutLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<div className="checkout-container">
<header className="checkout-header">
<Logo />
<CheckoutProgress />
</header>
{children}
</div>
)
}
// app/checkout/template.tsx
'use client'
import { useEffect } from 'react'
import { trackPageView } from '@/lib/analytics'
export default function CheckoutTemplate({
children,
}: {
children: React.ReactNode
}) {
useEffect(() => {
trackPageView('checkout_step')
return () => {
// Cleanup runs on every navigation
console.log('Checkout step exited')
}
}, [])
return (
<div className="checkout-step-wrapper">
{children}
</div>
)
}This pattern gives developers fine-grained control over component lifecycle. The layout maintains the checkout header and progress indicator across all steps. The template ensures analytics tracking fires on every step transition and cleanup logic runs when users leave each step.
The nesting order matters critically. Next.js applies layouts first, then templates, then the page component. This means the layout wraps the template, and the template wraps the page. Understanding this hierarchy prevents confusion about which wrapper controls which lifecycle events.
Making the Right Choice for Your App
The layout versus template decision shapes your application's user experience at a fundamental level. Developers who understand the distinction build applications that feel responsive and polished. Those who don't end up with janky transitions and mysterious state bugs.
Start with layouts as your default pattern. They provide better performance and more intuitive behavior for most use cases. Reach for templates only when you have a specific requirement for state resets or effect re-execution.
The framework makes both patterns equally accessible, but the patterns themselves serve different purposes. Layouts optimize for persistence and performance. Templates optimize for clean state and explicit lifecycle control.
That covers the essential patterns for layouts and templates in Next.js App Router. Apply these in production and the difference will be immediate. Your users won't see mysterious state persistence, your animations will behave predictably, and your application's performance will improve measurably.