skip to content

In the Next.js App Router, what is the difference between a segment's layout.tsx and its template.tsx, and how does that difference show up when the user navigates between two pages under that segment?

level: middleimportance: must knowfreq 78%

answer

  1. one persists, one restarts
  2. children swap under a stable parent
  3. fresh instance on every navigation
  4. effects re-run, state resets
  5. layout wraps template wraps page

basics

~20 s

A layout persists across navigation: its instance stays mounted, state and effects survive, only the child page swaps. A template wraps children the same way but is remounted on every navigation, so state resets, effects re-run, and DOM nodes are recreated.

solid answer

~50 s

Both files wrap everything below their segment and both receive a `children` prop, so structurally they look identical. The difference is instance lifetime. `layout.tsx` is preserved when you move between routes that share it — React keeps the same element in the tree, so a client component's state inside it survives, `useEffect` does not re-run, and DOM nodes such as a scrolled sidebar keep their scroll position; on client navigation Next only re-renders the segments that actually changed. `template.tsx` gives each navigation a fresh instance: state is not preserved, effects re-synchronize, and the DOM is rebuilt. When both exist in a folder, the layout wraps the template, which wraps the page. So layout is the default, and template is the deliberate opt-in when you need per-navigation enter animations, per-view effects, or a reset of state that a layout would otherwise carry across.

code

tsx · 10 lines
tsx
import type { ReactNode } from 'react';

export default function DashboardLayout({ children }: { children: ReactNode }) {
  return (
    <div className="dashboard">
      <aside className="sidebar">Persistent navigation</aside>
      <main>{children}</main>
    </div>
  );
}

go deeper

for a junior

Know that both files wrap the routes below them and both take a children prop, and be able to say plainly that a layout stays mounted across navigation while a template is rebuilt each time.

for a middle

Explain the observable consequences: state kept or reset, effects skipped or re-run, DOM nodes reused or recreated, and the fact that Next only re-renders the segments that changed. Name the layout → template → page nesting order.

for a senior

Show judgment about cost. Be ready to say why a template is the exception rather than the default, what remounting an entire subtree throws away on every navigation, and how you would diagnose a shell that unexpectedly resets or an animation that never replays.

for a principal

Own the convention. Decide where shared chrome lives across a large route tree, keep expensive fetching out of components that remount per navigation, and write down the team rule for when a reset is a real product requirement rather than a workaround for misplaced state.

## The segment tree In the App Router every folder under `app/` is a URL segment, and a segment can hold two pieces of UI: `page.tsx`, which is unique to that exact URL, and `layout.tsx`, which is shared by that segment and everything nested beneath it. Layouts compose down the tree — the root layout wraps the dashboard layout, which wraps the page — and each one receives the level below it as its `children` prop. ```tsx // app/dashboard/layout.tsx import type { ReactNode } from 'react'; export default function DashboardLayout({ children }: { children: ReactNode }) { return ( <div className="dashboard"> <Sidebar /> {children} </div> ); } ``` ## What "persists" actually means Navigate from `/dashboard/overview` to `/dashboard/settings` and both routes sit under the same `app/dashboard/layout.tsx`. Next does not throw that layout away and build it again. The layout element stays in the same position of the React tree, and only the `children` slot is replaced. Four concrete consequences follow: - Component state inside the layout survives. A client component holding an open/closed menu flag keeps its value. - `useEffect` inside the layout does not re-run — it was never unmounted, and its dependencies did not change. - The layout's DOM nodes are not recreated, so a sidebar the user scrolled stays where they left it, and a CSS or JS animation that ran on mount does not run again. - On client-side navigation Next requests only the segments that changed. The layout's own server render is not repeated, which is why a value it fetched on first load can go stale while the user moves around inside it. This is the behaviour interviewers are probing. "What actually re-renders on navigation?" has a precise answer in the App Router: the changed segments, not the shared ones. ## What template.tsx does differently `template.tsx` has the same shape — a default export taking `children` — but Next mounts a **new instance** of it on every navigation. State is not preserved, effects re-synchronize, and the DOM elements it produces are recreated. Conceptually it behaves as though Next handed the component a fresh key on each route change. ```tsx // app/dashboard/template.tsx import type { ReactNode } from 'react'; export default function DashboardTemplate({ children }: { children: ReactNode }) { return <div className="fade-in">{children}</div>; } ``` That `fade-in` class re-triggers its animation on every navigation precisely because the element is new each time. Put the same markup in the layout and the animation runs once, on first load, and never again. ## How they nest When a folder has both files, the order is layout → template → page. The layout is the stable outer shell; the template is the disposable inner wrapper; the page is the content. That ordering is what makes the pairing useful: a sidebar in the layout keeps its scroll while the content area inside the template restarts its transition on each route change. ## When a template is the right answer Templates are a narrow tool. The cases that genuinely need one: - **Enter transitions per route.** Animation on mount only fires if there is a mount. - **Per-view effects.** Logging a page view, or any `useEffect` that must fire once per navigation rather than once per session. - **Deliberate state reset.** A feedback widget, filter panel, or draft form that should start clean whenever the user moves to a different route under that segment. Everything else belongs in a layout. Remounting is not free: a template forces its whole subtree to be rebuilt on every navigation beneath it, discarding exactly the work the App Router's partial rendering was designed to keep. Reaching for `template.tsx` "just in case" turns a cheap segment swap into a full re-mount. ## The interview test Reduce it to one question about the UI in front of you: *should this survive the navigation, or restart on it?* Shared chrome, navigation state, scroll containers and long-lived subscriptions survive — layout. Transitions, per-view analytics and anything the user should see fresh restart — template. A candidate who can state that rule, and then name the four observable consequences (state, effects, DOM identity, re-render scope), has answered the question completely.

  • When a folder contains both layout.tsx and template.tsx, which one is the outer wrapper?
    The layout is outermost: layout wraps template, which wraps the page. That ordering is the point of using both — the layout holds the chrome that must survive the navigation, while the template is the inner wrapper Next recreates on each route change, so the content area can animate or reset without disturbing the shell around it.
  • Give a concrete feature that genuinely requires template.tsx instead of layout.tsx.
    A per-route enter animation, since a CSS or JS animation on mount only fires when something actually mounts. Same for an effect that must log one page view per navigation, or a filter panel and draft form that should start empty every time the user moves to a sibling route. In a layout all three would fire once and then never again.
  • Does switching from a layout to a template change anything on the server, or only on the client?
    Both are Server Components by default, so it changes both. A shared layout's server render is skipped on client navigation because Next only re-renders changed segments. A template is re-rendered for each set of children, so its server work repeats on every navigation beneath it — which is why an expensive data fetch does not belong in a template.

saying these in an interview costs you the question

  • Layout and template are two names for the same thing
  • A layout re-renders on every route change
  • template.tsx replaces layout.tsx in that folder
  • Use a template whenever you want state in the shell
  • Layouts persist because Next caches their HTML

context