Type something to search...
Next.js template.js

Next.js template.js

layout.js persists across navigations by design — that's precisely why it's useful for shared UI. But sometimes persistence is exactly what you don't want: a form that should clear when you navigate away and back, an animation that should replay on every visit, a useEffect that needs to resynchronize each time a segment mounts fresh rather than assuming it's still the same component instance it was a moment ago. template.js looks almost identical to a layout on the surface — same "wraps children" shape — but makes the opposite tradeoff: instead of persisting, it gets a fresh, uniquely-keyed instance on every navigation to its segment.

Basic Shape

export default function Template({ children }: { children: React.ReactNode }) {
  return <div>{children}</div>;
}

Structurally this is indistinguishable from the simplest possible layout — a component accepting children and rendering them. The entire difference is behavioral, not syntactic, and it comes from one specific mechanism: React gives the template a unique key on each navigation, and a changed key is React's own built-in signal to unmount the old instance and mount an entirely new one, discarding whatever state it held.

Where It Sits in the Hierarchy

template.js renders between a layout and its children — wrapping error.js, loading.js, not-found.js, and page.js, but not wrapping the layout.js at the same segment level:

<Layout>
  {/* Note that the template is given a unique key. */}
  <Template key={routeParam}>{children}</Template>
</Layout>

That placement is the whole point: the layout above it stays mounted and persistent as usual, while the template below it resets — giving you a boundary where you can deliberately choose to not inherit the layout's persistence, for exactly the segment where you need a fresh start on every visit.

What Actually Resets

Four concrete, related effects fall out of the remount:

  • Client Component state resets — any local useState inside a Client Component nested in the template is wiped on navigation, since the component instance holding that state no longer exists after the remount.
  • Effects re-runuseEffect hooks resynchronize, because from React's perspective this is a brand-new mount, not a re-render of an existing one.
  • DOM elements are fully recreated — not just React's virtual representation, but the actual underlying DOM nodes get torn down and rebuilt.
  • Suspense fallback behavior changes — this is a subtle one worth calling out explicitly: Suspense boundaries inside an ordinary layout only show their fallback on the first load, since the layout persists afterward and the Suspense boundary isn't remounting on subsequent navigations. Suspense boundaries inside a template, by contrast, show their fallback on every navigation, precisely because the template — and everything inside it — remounts every time.

When You Actually Want This

The docs frame three specific, concrete motivations, and it's worth internalizing them as the litmus test for "do I need a template here, or is this actually just a layout":

  • Resynchronizing useEffect on every navigation, rather than only once when a persistent layout first mounts.
  • Resetting a specific Client Component's local state on navigation — a search input that should clear, a multi-step form that should restart, an accordion whose expanded/collapsed state shouldn't carry over from whatever the user was previously looking at.
  • Deliberately changing the default Suspense-fallback-only-on-first-load behavior to "fallback on every navigation," when that's genuinely the UX you want.

If none of these apply — if you just want shared UI without caring whether it resets — you want a plain layout, not a template. Templates cost you the persistence layouts give you for free, so reach for one specifically when resetting is the actual requirement, not as a default choice.

Navigation Behavior: Which Level Actually Remounts

This is the part of the reference that's easy to get wrong by intuition, since "remounts on navigation" sounds simple until you have templates nested at multiple levels simultaneously. The key insight: a template's key is tied to its own segment level, and only changes when the params for that specific segment change — navigations happening entirely within a deeper child segment don't touch a parent template's key at all, and search params never trigger a remount regardless of level.

Walking through a concrete tree makes this precise:

app
├── about
│   └── page.tsx
├── blog
│   ├── [slug]
│   │   └── page.tsx
│   ├── page.tsx
│   └── template.tsx
├── layout.tsx
├── page.tsx
└── template.tsx

Starting at /, the tree is:

<RootLayout>
  <Template key="/">
    <Page />
  </Template>
</RootLayout>

Navigate to /about — the first segment itself changed, so the root template's key changes and it remounts:

<RootLayout>
  <Template key="/about">
    <AboutPage />
  </Template>
</RootLayout>

Navigate to /blog — first segment changes again, so the root template remounts, and the blog-level template (which didn't exist in the previous tree at all) now mounts fresh:

<RootLayout>
  <Template key="/blog">
    <Template key="/blog">
      <BlogIndexPage />
    </Template>
  </Template>
</RootLayout>

Now navigate within the blog section, to /blog/first-post — the first segment (blog) hasn't changed at all, so the root template's key stays the same and it does not remount. But the child segment did change, so the blog-level template's key changes and it remounts:

<RootLayout>
  <Template key="/blog">
    {/* remounts because the child segment at this level changed */}
    <Template key="/blog/first-post">
      <BlogPostPage slug="first-post" />
    </Template>
  </Template>
</RootLayout>

And navigating again to /blog/second-post repeats exactly the same pattern — root template untouched, blog-level template remounts again with a new key:

<RootLayout>
  <Template key="/blog">
    <Template key="/blog/second-post">
      <BlogPostPage slug="second-post" />
    </Template>
  </Template>
</RootLayout>

The rule this all reduces to: a template only remounts when the segment it belongs to changes — not when any navigation happens anywhere in the app. A template nested three levels deep is completely indifferent to navigations happening at levels above it, as long as its own segment's params stay the same.

Behavior Summary

  • Templates are Server Components by default, same as everything else, and can be Client Components via "use client" if needed.
  • They receive a unique key scoped to their own segment, remounting specifically when that segment (including its dynamic params) changes.
  • Search params changing alone never triggers a remount — only changes to the actual route segment/params do.

Version History

VersionChanges
v13.0.0template introduced

Key Takeaways

LayoutTemplate
Persists across navigationRemounts fresh on navigation to its own segment
State survivesState resets
Effects don't re-run on sibling navigationEffects always resynchronize
Suspense fallback shows once (first load)Suspense fallback shows on every navigation
Default choice for shared UIReach for it specifically when reset behavior is the actual requirement

template.js is a narrow-purpose tool, and that's exactly its value — it exists so you don't have to hand-roll key-based remounting logic yourself every time a specific segment genuinely needs a clean slate on every visit. Reach for it deliberately, understand which segment level actually controls its remount timing, and default back to a plain layout everywhere else.

Tags :
Share :

Related Posts

Can Next.js Be Used with GraphQL?

Can Next.js Be Used with GraphQL?

Next.js and GraphQL are two powerful technologies that have gained significant traction in the web development community. Next.js, a React-based fram

Dive Deeper
How does Next.js differ from Create React App?

How does Next.js differ from Create React App?

In the world of modern web development, React.js has emerged as a dominant force due to its flexibility, performance, and extensive ecosystem. Two po

Dive Deeper
How does Next.js handle image optimization?

How does Next.js handle image optimization?

In modern web development, image optimization plays a critical role in enhancing user experience and improving site performance. Large, unoptimized i

Dive Deeper