Templates
template.tsx file looks almost identical to layout.tsx — both wrap the pages beneath them in shared UI, and both accept a children prop. The difference is subtle but important: a layout persists across navigations within the same segment, while a template creates a brand-new instance every time the user navigates between routes it wraps.app/dashboard/template.tsx
export default function Template({
children,
}: {
children: React.ReactNode
}) {
return <div className="dashboard-transition">{children}</div>
}Why that difference matters
useState initializes fresh, and useEffect re-runs its setup logic every time the route changes — even if the user is navigating between sibling pages that share the same layout. A layout, by contrast, stays mounted, so its state and effects survive navigation between its child routes.template.tsx. If you don't need fresh state or a fresh effect run on every navigation, a layout is almost always the better (and cheaper) choice.A worked example — per-page enter animation
A common use case is a fade-in or slide-in animation that should replay every time a new page mounts. Because a layout would only run its mount effect once (on first load), it can't replay an animation on every navigation — but a template can, since it re-mounts each time.
app/(marketing)/template.tsx
'use client'
import { useEffect, useState } from 'react'
export default function Template({
children,
}: {
children: React.ReactNode
}) {
const [visible, setVisible] = useState(false)
useEffect(() => {
// Runs again on every navigation because the template re-mounts.
setVisible(true)
}, [])
return (
<div
style={{
opacity: visible ? 1 : 0,
transition: 'opacity 200ms ease-in',
}}
>
{children}
</div>
)
}<Suspense> boundary's fallback on every navigation, or logging analytics events that should fire once per page view rather than once per layout mount.Layout and template together
layout.tsx and a template.tsx at the same time. When it does, Next.js renders the layout first (which persists), and the template renders inside it, wrapping the page (and re-mounting on every navigation). The rendered tree looks like Layout > Template > Page.Folder structure
app/
dashboard/
layout.tsx // persists across dashboard navigations
template.tsx // re-mounts on every dashboard navigation
page.tsx
settings/
page.tsxLayout vs template
Behavior | layout.tsx | template.tsx |
|---|---|---|
Persists state across navigation | Yes | No — resets |
Re-renders / re-mounts on navigation | No — stays mounted | Yes — mounts fresh each time |
| No | Yes |
Typical use case | Shared nav, sidebar, persistent UI state | Enter/exit animations, per-page analytics, resetting form state |
template.tsxlooks likelayout.tsxbut creates a new instance on every navigation.State and effects inside a template reset on each navigation; inside a layout, they persist.
Use templates for per-page enter/exit animations or logic that must run fresh on every page view.
A segment can define both — the render order is Layout > Template > Page.