Loading...
Loading...
In the Next.js App Router layouts and templates define the shared structure of pages. A layout wraps child pages and preserves its state during navigation. A template does the same but is recreated on every transition.
A layout is a component shared between multiple pages. When navigating between child pages the layout does not remount and preserves state:
// app/layout.tsx (root layout)
export default function RootLayout({
children
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<Header />
<main>{children}</main>
<Footer />
</body>
</html>
)
}
The root layout is required and must contain <html> and <body> tags.
Layouts can be nested. Each segment can have its own layout:
// app/docs/layout.tsx
export default function DocsLayout({
children
}: {
children: React.ReactNode
}) {
return (
<div className="flex">
<DocsSidebar />
<div className="flex-1">{children}</div>
</div>
)
}
When a user navigates between documentation pages on Hack Frontend, the sidebar does not remount. This provides a smooth UX.
The key property of a layout: when navigating between child pages React does not remount the layout. This means:
'use client'
// app/problems/layout.tsx
import { useState } from 'react'
export default function ProblemsLayout({
children
}: {
children: React.ReactNode
}) {
const [filter, setFilter] = useState('all')
return (
<div>
<FilterBar value={filter} onChange={setFilter} />
{children}
</div>
)
}
The filter will persist when navigating between /problems/1 and /problems/2.
A template works like a layout but is recreated on every navigation:
// app/docs/template.tsx
export default function DocsTemplate({
children
}: {
children: React.ReactNode
}) {
return <div>{children}</div>
}
| Layout | Template | |
|---|---|---|
| Remounting | No | Yes, on every navigation |
| State (useState) | Preserved | Reset |
| useEffect | Does not rerun | Runs again |
| DOM | Not recreated | Recreated |
Layout wraps other special files in a specific order:
layout.tsx
template.tsx
error.tsx (React Error Boundary)
loading.tsx (React Suspense)
not-found.tsx
page.tsx
Practical tip:
In most cases use layout. Template is only needed when you need to reset state or fire effects on navigation.