---
title: "07 — Layouts and Templates — Shared UI That Does (or Doesn't) Persist"
uid: layouts-templates
tags: ["roadmap:nextjs", "layouts", "templates", "routing", "app-router", "nextjs"]
excerpt: "Two file conventions that look identical differ in one behavior: layouts persist across navigation (state preserved), templates remount fresh every time (state reset)."
date: 2026-08-13T03:28:02+0000
source: https://www.aveshina.my.id/en/blog/layouts-templates
---

Two App Router conventions that look almost identical turned out to differ in exactly one behavior — and that behavior is the whole decision. The model that clicked: **both wrap child routes, but layouts persist across navigation while templates create a fresh instance on every navigation** [1][2]. That single difference — persist vs. reset — is the entire decision between them.

## Layouts — the persistent wrapper

A layout.tsx wraps the pages (and nested layouts) beneath it. The key behavior is **persistence**: when the user navigates between routes that share a layout, the layout component does not remount. Its state survives, its effects don't re-run, and its DOM stays put [1].

```
// app/layout.tsx — root layout, persists across every navigation
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        <nav>Always-here navigation</nav>
        {children}
      </body>
    </html>
  );
}
```

The root layout is mandatory and persists for the entire app — that's where the <html> and <body> tags live. Nested layouts persist within their subtree: a dashboard/layout.tsx wraps every page under /dashboard/* and doesn't remount when moving between dashboard pages.

The payoff is the things I don't want to lose on navigation: a sidebar's scroll position, a video player's playback, a tab's open state, a complex form's partial input. Because the layout's state isn't reset, those survive.

## Templates — the resetting wrapper

A template.tsx is structurally similar — it wraps each child layout or page — but the behavior is the opposite [3]. On every navigation, a template creates a **new instance** of its children: the component remounts, DOM elements are recreated, useState resets, and effects re-synchronize.

```
// app/template.tsx — new instance on every navigation
export default function Template({ children }: { children: React.ReactNode }) {
  return <div className="page-transition">{children}</div>;
}
```

When templates are useful is the question worth asking. The roadmap's framing: templates are for when I *want* the reset [3] — animation entry points that should replay on every navigation, effects that must re-run per page view (analytics pageviews, for instance), or cases where stale state is a bug rather than a feature.

```figure
<svg viewBox="0 0 720 280" xmlns="http://www.w3.org/2000/svg" class="my-6 w-full max-w-2xl" role="img" aria-label="Layout versus template across two navigations. Top row (layout): nav from /a to /b — the wrapper component stays glowing, state persists, children swap. Bottom row (template): nav from /a to /b — the wrapper remounts, state resets, effects re-run.">
  <g font-family="ui-sans-serif, system-ui, sans-serif" text-rendering="geometricPrecision">

    <!-- Layout row -->
    <text x="360" y="24" font-size="12" font-weight="700" fill="#052e16" text-anchor="middle">layout.tsx — persists across navigation</text>
    <rect x="40" y="40" width="640" height="80" rx="8" fill="#dcfce7" stroke="#16a34a" stroke-width="1.5"/>
    <text x="60" y="62" font-size="11" font-weight="700" fill="#052e16">layout (state survives)</text>
    <rect x="60" y="74" width="120" height="36" rx="6" fill="#fef9c3" stroke="#ca8a04" stroke-width="1"/>
    <text x="120" y="96" font-size="10" font-family="ui-monospace, monospace" fill="#422006" text-anchor="middle">/a</text>
    <text x="210" y="96" font-size="14" fill="#16a34a" text-anchor="middle">→</text>
    <rect x="240" y="74" width="120" height="36" rx="6" fill="#fef9c3" stroke="#ca8a04" stroke-width="1"/>
    <text x="300" y="96" font-size="10" font-family="ui-monospace, monospace" fill="#422006" text-anchor="middle">/b</text>
    <text x="440" y="96" font-size="10" font-style="italic" fill="#052e16">children swap, layout stays mounted</text>

    <!-- Template row -->
    <text x="360" y="160" font-size="12" font-weight="700" fill="#7f1d1d" text-anchor="middle">template.tsx — resets on every navigation</text>
    <rect x="40" y="176" width="640" height="80" rx="8" fill="#fee2e2" stroke="#dc2626" stroke-width="1.5"/>
    <text x="60" y="198" font-size="11" font-weight="700" fill="#7f1d1d">template (state resets)</text>
    <rect x="60" y="210" width="120" height="36" rx="6" fill="#fef9c3" stroke="#ca8a04" stroke-width="1"/>
    <text x="120" y="232" font-size="10" font-family="ui-monospace, monospace" fill="#422006" text-anchor="middle">/a (instance 1)</text>
    <text x="210" y="232" font-size="14" fill="#dc2626" text-anchor="middle">→</text>
    <rect x="240" y="210" width="120" height="36" rx="6" fill="#fef9c3" stroke="#ca8a04" stroke-width="1"/>
    <text x="300" y="232" font-size="10" font-family="ui-monospace, monospace" fill="#422006" text-anchor="middle">/b (instance 2)</text>
    <text x="440" y="232" font-size="10" font-style="italic" fill="#7f1d1d">everything remounts, effects re-run</text>
  </g>
</svg>
```

## The default is layout

For the vast majority of shared UI — site chrome, persistent navigation, authentication context providers — layout is the right choice, because I don't want a sidebar's scroll position reset every time I click a link. Templates are the deliberate exception, reached for when "fresh on every navigation" is the desired behavior.

## How I use this

I default to layout.tsx for everything that wraps multiple routes. The only times I reach for template.tsx are when I'm building a per-page-view animation that must replay, or wiring an analytics call that has to fire on every navigation regardless of caching. The question I ask: *should this state survive a navigation?* Yes → layout. No → template.

## References

[1] Vercel, "Layouts (App Router)," Next.js Docs, 2024. [Online]. Available: [https://nextjs.org/docs/app/api-reference/file-conventions/layout#root-layouts](https://nextjs.org/docs/app/api-reference/file-conventions/layout#root-layouts)

[2] Vercel, "Layouts (Pages Router)," Next.js Docs, 2024. [Online]. Available: [https://nextjs.org/docs/pages/building-your-application/routing/pages-and-layouts](https://nextjs.org/docs/pages/building-your-application/routing/pages-and-layouts)

[3] Vercel, "Templates," Next.js Docs, 2024. [Online]. Available: [https://nextjs.org/docs/app/api-reference/file-conventions/template](https://nextjs.org/docs/app/api-reference/file-conventions/template)

[4] D. Pierce, "A guide to Next.js layouts and nested layouts," LogRocket Blog, 2023. [Online]. Available: [https://blog.logrocket.com/guide-next-js-layouts-nested-layouts/](https://blog.logrocket.com/guide-next-js-layouts-nested-layouts/)

[5] "Next.js 15 tutorial — Layouts," YouTube, 2024. [Video]. Available: [https://www.youtube.com/watch?v=NK-8a8EzWrU](https://www.youtube.com/watch?v=NK-8a8EzWrU)

[6] "Next.js 15 tutorial — Templates," YouTube, 2024. [Video]. Available: [https://www.youtube.com/watch?v=yfww2kplO-k](https://www.youtube.com/watch?v=yfww2kplO-k)

```quiz
Q: When the user navigates between two routes sharing a layout.tsx, what happens to the layout?
- It remounts and resets its state
- It persists — state survives, effects don't re-run, DOM stays put
correct: 1
explain: Layouts persist across navigation between routes they wrap. That's the defining behavior, and it's why they're used for site chrome and state that should survive navigation.

Q: What's the key difference between layout.tsx and template.tsx?
- Nothing — they're aliases
- Templates create a new instance on every navigation (state resets, effects re-run); layouts persist
correct: 1
explain: Both wrap child routes, but templates remount their children on each navigation while layouts stay mounted. Templates are the choice when a reset is the desired behavior.

Q: Why would you reach for a template instead of a layout?
- To preserve a sidebar's scroll position across navigation
- When you want state reset and effects to re-run on every navigation (e.g., replaying an entry animation or firing a per-pageview analytics call)
correct: 1
explain: Templates are for cases where a fresh instance is desirable — animations that should replay, effects that must run per pageview. Layouts are the default when state should survive.

Q: The root layout.tsx is…
- optional
- mandatory, wraps the entire app, and is where <html> and <body> live
correct: 1
explain: Every App Router project requires a root layout that renders <html> and <body>. It persists across all navigation in the app.
```
