← All lessons
Lesson 05 · Beginner

Layouts & Templates

Share UI between pages without repeating yourself. Nested layouts unlock dashboards, marketing sites and more.

Most apps share a shell — a header, a sidebar, a footer. Putting that markup in every page is repetitive and bug-prone. The App Router solves this with layout.js files, which wrap a page and everything below it in the tree.

The root layout

Every app has one root layout at app/layout.js. It must include <html> and <body> tags, and it must accept and render children.

// app/layout.js
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <header>My site</header>
        {children}
        <footer>© 2026</footer>
      </body>
    </html>
  );
}

Nested layouts

Any folder can have its own layout.js. It wraps every route at that level and below. This is great for areas of the app that share UI — a dashboard with a sidebar, for instance.

app/
├─ layout.js               // header + footer for the whole site
├─ page.js                 // /
└─ dashboard/
   ├─ layout.js            // adds a sidebar
   ├─ page.js              // /dashboard
   └─ settings/page.js     // /dashboard/settings (also gets the sidebar)

The dashboard layout file looks the same as any other component — but it does not include <html> or <body> since the root layout already does:

// app/dashboard/layout.js
export default function DashboardLayout({ children }) {
  return (
    <div className="dashboard">
      <aside>Sidebar</aside>
      <section>{children}</section>
    </div>
  );
}

Layouts preserve state

When you navigate between two pages that share a layout, the layout does not re-render. Anything inside it — a sidebar's collapsed state, a search input value — keeps its state. This is one of the biggest wins of the App Router.

Templates

Sometimes you want the opposite: re-mount the wrapping UI on every navigation. Use template.js instead of layout.js. Same shape, different behavior. Templates are useful for entry animations or for resetting state on each visit.

Note: Use layouts by default. Reach for templates only when you specifically need the re-mount behavior.

Try it

Convert this layout so that every page in /marketing gets a banner above it. The /marketing/page.js content should appear in place of the placeholder.

Need a hint?

Layouts must accept and render the `children` prop.

Quiz

Pick the best answer. You only get one shot per question.

1. Which file is required at the top of an App Router app?

2. You navigate from /dashboard to /dashboard/settings. Both pages live under `app/dashboard/`. What happens to the dashboard layout?

3. When should you use `template.js` instead of `layout.js`?