NextjsTemplates

Templates

A 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

TSX
export default function Template({
  children,
}: {
  children: React.ReactNode
}) {
  return <div className="dashboard-transition">{children}</div>
}
Why that difference matters
Because React re-mounts a template on every navigation, any state held inside it (or inside its children, effectively) resets. That means 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.
Note
This re-mounting behavior is the single defining feature of 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

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>
  )
}
Other good use cases for templates include features that rely on a fresh mount to behave correctly — for example, resetting a <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
A route segment can define both a 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

Text
app/
  dashboard/
    layout.tsx     // persists across dashboard navigations
    template.tsx    // re-mounts on every dashboard navigation
    page.tsx
    settings/
      page.tsx
Layout 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

useEffect re-runs on navigation

No

Yes

Typical use case

Shared nav, sidebar, persistent UI state

Enter/exit animations, per-page analytics, resetting form state

Tip
Reach for a template only when you specifically need the re-mount behavior. For the vast majority of shared UI, a layout is simpler and avoids unnecessary re-renders.
  • template.tsx looks like layout.tsx but 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.