Templates
Trailhead wants each trail page to fade in when it opens and to record a page view for the "most visited trails" chart. You try both in the trails layout, and they work once. Then you click to the next trail and nothing happens: no fade, no log. The layout did exactly what layouts do. It stayed put.
The rule
A layout remembers; a template starts fresh on every navigation.
A template.tsx file looks just like a layout: it default-exports a component that receives children. The difference is lifetime. Next.js gives the template a new instance each time the route below it changes, so:
- its state resets to the initial values,
- its effects run again,
- entrance animations play again,
- the DOM elements inside it are created anew.
// app/trails/template.tsx
"use client";
import { useEffect } from "react";
import { usePathname } from "next/navigation";
export default function TrailsTemplate({ children }: { children: React.ReactNode }) {
const pathname = usePathname();
useEffect(() => {
fetch("/api/views", { method: "POST", body: pathname });
}, [pathname]);
return <div className="fade-in">{children}</div>;
}It is a client component here only because it uses useEffect and usePathname; a template without hooks can stay a server component.
When a folder has both files, the layout wraps the template, and the template wraps the page:
TrailsLayout # persists: sidebar keeps its filter
TrailsTemplate # re-created: fade and log run again
TrailPageSo you can combine them: persistent chrome in the layout, per-visit behaviour in the template.
| Layout | Template | |
|---|---|---|
Wraps children |
Yes | Yes |
| Survives navigation | Yes | No, re-created |
| State inside | Kept | Reset |
| Effects | Run once | Run on each navigation |
Most of the time you want a layout. Reach for a template only when you specifically need the "start over" behaviour.
The shortcut
Ask "Should this happen again on every page change?" If yes, template. If it should persist, layout. If both kinds of behaviour exist, split them across the two files.
Filter sidebar
Should keep its selection. Layout.
The trap is turning a layout into a template to get one effect to rerun. That throws away the persistence you wanted for everything else. Keep both files.
Drills
Answer fast — trust the rule.
What happens to state inside a template when the hiker moves to another trail?
A folder has both layout.tsx and template.tsx. How do they nest?
Which need is best served by a template rather than a layout?
What does a template component receive to render the page inside it?
Remember
- A layout remembers; a template starts fresh on every navigation.
- Shortcut: "should this happen again on every page change?" Yes means template.
- Trap: converting a layout to a template to rerun one effect. Use both files.
