Template

template.tsx wraps pages inside the layout chain - special file, no URL, nearest-wins.

Overview

template.tsx sits between the layout chain and the page. Like layout.tsx, it is a special file and does not create a URL. Unlike a layout, it is resolved per page scope and is a good place for effects that should run when navigating between pages.

app
layout.tsx
template.tsx
page.tsx
about
page.tsx
/
/about
FileCreates URL?Role
layout.tsxNo - special fileWraps segment + children, receives params
template.tsxNo - special fileWraps page inside layout chain, receives children
page.tsxYesRoute content
Templates only apply to routes inside the folder that declares them and its descendants. They receive children, not params.

What is template.tsx?

A template.tsx file wraps each page in its scope. The nearest template with a default export is used (nearest-wins, same as loading and error).

  • Between layout and page: renders inside the layout chain, around the page
  • children only: templates receive children, not route params
  • Folder-scoped: applies to that folder and descendants only
  • No URL: special file - does not create a route

template.tsx vs layout.tsx

Featurelayout.tsxtemplate.tsx
Creates URL?NoNo
WrapsSegment + all childrenPage inside layout chain
PropsOutlet / paramschildren
Typical useNav, sidebar, shared chromePage-level effects, transitions
LocationAny folderAny folder
app
layout.tsx
template.tsx
page.tsx
about
layout.tsx
template.tsx
page.tsx
/
/about

Creating a Template

Create template.tsx in any folder. It must have a default export and receives children.

app/template.tsx
export default function Template({
  children,
}: {
  children: React.ReactNode
}) {
  return <div>{children}</div>
}
app/template.tsx
export default function Template({
  children,
}: {
  children: React.ReactNode
}) {
  useEffect(() => {
    // Useful for analytics or focus management
    console.log('Template active')
  }, [])

  return <div>{children}</div>
}
app/dashboard/template.tsx
export default function DashboardTemplate({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <div className="animate-in fade-in">
      {children}
    </div>
  )
}
Templates that contain an html tag are ignored. Prefer simple wrappers around children.

Use Cases

Prefer a template when you need page-scoped behavior without changing the persistent layout chrome.

Use CaseWhy template?
Page transitionsWrap the page for enter/exit animation classes
Analytics / loggingRun effects around each page view
Focus managementMove focus when the page content changes
Reset local UI stateKeep layout state, re-init page-level UI

File Naming - templates.tsx

On this docs site, the page file is named templates.tsx (plural) so it is not treated as the special template.tsx convention. The real special file in apps remains template.tsx.

Real special fileDocs page fileWhy?
app/template.tsxapp/docs/templates.tsxAvoid special-file handling for the docs route
app/default.tsxapp/docs/defaults.tsxSame idea for slot defaults

Complete Example

Templates next to layouts, loading, and error - special files do not create URLs.

app
layout.tsx
template.tsx
loading.tsx
error.tsx
page.tsx
dashboard
layout.tsx
template.tsx
page.tsx
settings
page.tsx
/
/dashboard
/dashboard/settings
FileCreates URL?Purpose
app/layout.tsxNoRoot layout
app/template.tsxNoRoot template
app/page.tsxYes - /Home page
app/dashboard/template.tsxNoDashboard page wrapper
app/dashboard/page.tsxYes - /dashboardDashboard page
Use layout.tsx for shared chrome. Use template.tsx for page-level wrapping inside that chrome.
Was this helpful?