Layout vs Template — Persistent State vs Fresh Mount Every Time
Layout vs Template — Persistent State vs Fresh Mount Every Time
💡 Why Does This Matter? — Whether State Lives or Dies
Layout · Template · State Persistence Model
1. layout.tsx — Stays Mounted Across Child Navigations
- ▸Navigating from
/dashboard/poststo/dashboard/users: the layout stays intact; onlychildrenis swapped to the new page. - ▸If a Client Component inside the layout holds
useState, that state is preserved.
2. template.tsx — Freshly Mounted Every Time
- ▸Navigating from
/dashboard/poststo/dashboard/users: the template remounts → the fade-in animation plays again. - ▸Ideal for per-page entrance animations and pageview tracking (when
useEffectmust fire on every page entry).
3. Both Can Coexist
Render order: layout > template > page. On navigation, the layout survives; the template and page remount each time.
4. Visualization — State Persistence Model
5. When to Use Which?
Use template only when you truly need it. Mindless use of template = remount cost on every navigation + visual flicker.
💡 💡 Layout vs Template Decision Guide
1. Default to layout. Use template only when you can justify why.
Mindless use of template = remount cost every navigation + user frustration from unexpected state resets.
2. Ask yourself: 'Should this state survive page navigation?'
- ▸Yes → layout (sidebar · global shell · currently playing video player)
- ▸No → template (start clean on each page)
3. Three clear signals that you need template
- ▸Page transition animations (fade-in · slide-in)
- ▸Pageview analytics —
useEffectmust fire on every page entry - ▸Form auto-reset — blank state even after leaving and returning
4. Even a 'use client' layout.tsx preserves its state
Whether the layout is a Server Component or a Client Component, the instance is kept alive. useState inside a Client layout works and persists normally.
5. Both only receive children — they cannot directly receive page props
Both layout and template can receive params (for dynamic routes), but they cannot receive data props from the page. Pages must fetch their own data.