Lesson 5 of 2222 min read

Understanding Pages and Layouts in Next.js

Learn how app/page.tsx and layout.tsx work together in the App Router, and how nested layouts let you share UI across groups of pages.

Author: CodersNexus

Understanding Pages and Layouts in Next.js

Once you understand that app/ powers routing through folder structure, the next question is: how do you avoid repeating the same navbar, footer, and wrapper markup on every single page? The App Router answers this with two distinct, purpose-built files — page.tsx and layout.tsx — that together let you define unique content per route while sharing common UI across many routes without duplication or unnecessary re-rendering.

This lesson goes deeper into how these two files interact, what a root layout is and why every App Router project must have one, and how nested layouts let you apply different shared UI to different sections of a site — for example, a marketing layout for public pages and a completely different dashboard layout for authenticated pages.

Learning Objectives

  • Explain the distinct responsibilities of page.tsx and layout.tsx.
  • Understand why every App Router project requires a root layout.
  • Build nested layouts that apply shared UI to specific sections of a site.
  • Recognize that layouts persist across navigation without re-rendering.
  • Identify how the children prop connects a layout to its nested content.

Core Definitions

  • page.tsx: The file that defines the unique, primary content for a specific route.
  • layout.tsx: The file that defines UI shared across a page and any of its nested routes, wrapping them via a children prop.
  • Root layout: The required top-level layout.tsx at app/layout.tsx that wraps the entire application, including the mandatory <html> and <body> tags.
  • Nested layout: A layout.tsx placed inside a subfolder of app/, applying additional shared UI only to routes within that subfolder.
  • children prop: A special prop automatically passed to a layout component, representing whatever page or nested layout is rendered inside it.
  • Route segment: A single folder within the app/ directory that corresponds to one part of a URL path.

Detailed Explanation

Every App Router project must have exactly one root layout at app/layout.tsx. This file is special: it must contain the <html> and <body> tags, since it's the outermost wrapper for your entire application — no other layout can replace this responsibility. Inside the root layout, a children prop represents whatever page or nested layout should render inside it, and React automatically supplies this value; you never pass it manually.

page.tsx and layout.tsx solve different problems. page.tsx answers 'what unique content lives at this exact URL?' while layout.tsx answers 'what shared UI should wrap this page and everything nested beneath it?' A single layout.tsx can wrap many page.tsx files if those pages live in nested folders beneath it.

This is where nested layouts become powerful. Imagine a project with app/layout.tsx (root layout with global navbar) and app/dashboard/layout.tsx (a second layout containing a sidebar, specific to dashboard pages). Any page inside app/dashboard/ — such as app/dashboard/settings/page.tsx — automatically renders inside BOTH layouts: first wrapped by the dashboard sidebar layout, which is itself wrapped by the root layout's navbar. Pages outside app/dashboard/, like the homepage, only pass through the root layout, never seeing the sidebar.

A crucial performance detail: layouts persist across navigation within their scope. If a user clicks from /dashboard/settings to /dashboard/billing, the dashboard sidebar layout does NOT re-render or re-fetch its data — only the page.tsx content inside it swaps out. This preserves UI state (like scroll position or open menus) in the layout and avoids redundant work, a meaningful advantage over full-page reloads or layouts re-implemented per-page in older routing systems.

Diagram Description

Visualize a nested wrapping diagram:

app/layout.tsx (ROOT — has <html>/<body>, contains global Navbar)
└── app/page.tsx → Homepage: Navbar only
└── app/dashboard/layout.tsx (Sidebar)
└── app/dashboard/page.tsx → Navbar + Sidebar + Dashboard home
└── app/dashboard/settings/page.tsx → Navbar + Sidebar + Settings content
└── app/dashboard/billing/page.tsx → Navbar + Sidebar + Billing content

Navigating between settings <-> billing: Sidebar layout stays mounted, only inner page.tsx content swaps.

Comparison Table

FileRequired?ResponsibilityRe-renders on navigation within its scope?
app/layout.tsxYes (exactly one, at root)Wraps entire app; must include <html>/<body>No — persists
app/[section]/layout.tsxOptionalWraps only routes nested inside [section]No — persists within that section
app/page.tsxYes, per routeUnique content for that specific URLYes — swaps per route

Next.js Practical Example

// app/layout.tsx — ROOT layout (required, has <html>/<body>)
import './globals.css';
import Navbar from '@/components/Navbar';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Navbar />
        {children}
      </body>
    </html>
  );
}

// app/dashboard/layout.tsx — NESTED layout, only wraps /dashboard/* routes
import Sidebar from '@/components/Sidebar';

export default function DashboardLayout({ children }: { children: React.ReactNode }) {
  return (
    <div style={{ display: 'flex' }}>
      <Sidebar />
      <section>{children}</section>
    </div>
  );
}

// app/dashboard/settings/page.tsx — unique page content
export default function SettingsPage() {
  return <h1>Account Settings</h1>;
}

When a user visits /dashboard/settings, Next.js composes three pieces automatically: RootLayout wraps everything with the Navbar, DashboardLayout wraps dashboard routes with the Sidebar, and SettingsPage supplies the unique heading content. The children prop is how each layout knows what to render inside itself — RootLayout's children resolves to DashboardLayout's entire output, and DashboardLayout's children resolves to SettingsPage's output. If the user then navigates to /dashboard/billing, only the innermost page.tsx content changes; both RootLayout and DashboardLayout remain mounted without re-rendering.

Industry Examples

  • SaaS products commonly use a root layout for marketing pages (navbar, footer) and a completely separate dashboard layout (sidebar, top bar) applied only to authenticated app routes.
  • E-commerce platforms use a nested checkout layout that strips away the main site navbar and footer during checkout to reduce distractions and cart abandonment.
  • Documentation sites use a nested docs layout with a persistent sidebar table of contents, so navigating between doc pages doesn't reset scroll position or collapse expanded menu sections.
  • Admin panels use nested layouts per major section (e.g., app/admin/users/layout.tsx vs app/admin/billing/layout.tsx) to show section-specific sub-navigation.
  • Multi-tenant platforms sometimes use nested layouts keyed by an organization or workspace segment, so each workspace can show a customized header while still inheriting the app-wide root layout.

Interview Questions and Answers

Q1. What is the difference between page.tsx and layout.tsx in the Next.js App Router?

page.tsx defines the unique content rendered for a specific route/URL. layout.tsx defines shared UI that wraps a page and any of its nested routes, such as a navbar or sidebar, and persists across navigation within its scope rather than re-rendering per page.

Q2. Why must every Next.js App Router project have a root layout?

The root layout at app/layout.tsx is required because it must contain the <html> and <body> tags, which are mandatory for a valid HTML document. Every other page and nested layout in the application renders inside this root layout via its children prop.

Q3. How does the children prop work in a layout component?

React and Next.js automatically pass whatever is nested inside a layout — either a page or another nested layout — as the children prop. The layout component renders {children} at the position where nested content should appear, without needing to manually specify what that content is.

Q4. What happens to a layout when a user navigates between two pages nested within it?

The layout persists and does not re-render or lose its state; only the page.tsx content inside it swaps out. This means UI like scroll position, open dropdowns, or in-progress form state within the layout itself is preserved across navigation.

Q5. Can a Next.js app have multiple layouts?

Yes. Beyond the single required root layout, any folder within app/ can define its own layout.tsx, creating a nested layout that applies only to routes within that folder and its subfolders, while still being wrapped by all layouts above it.

MCQs With Answers

1. Which file must contain the <html> and <body> tags in an App Router project?

  1. Any page.tsx
  2. The root app/layout.tsx
  3. globals.css
  4. next.config.js

Answer: B. The root app/layout.tsx

Explanation: The root layout is the outermost wrapper for the entire application and is required to include the <html> and <body> tags.

2. What does the children prop represent inside a layout component?

  1. The layout's own static content
  2. Whatever page or nested layout is rendered inside it
  3. A list of all routes in the app
  4. The site's navigation menu

Answer: B. Whatever page or nested layout is rendered inside it

Explanation: children is automatically supplied by Next.js/React to represent the nested page or layout that should render at that position.

3. If app/dashboard/layout.tsx exists, which routes does it wrap?

  1. Every route in the entire app
  2. Only routes nested inside app/dashboard/
  3. Only the homepage
  4. No routes until manually imported

Answer: B. Only routes nested inside app/dashboard/

Explanation: A nested layout only applies to routes within its own folder and any subfolders beneath it, not the entire application.

4. What happens to a shared layout's state when navigating between two pages it wraps?

  1. It resets completely
  2. It persists without re-rendering
  3. It throws an error
  4. It duplicates itself

Answer: B. It persists without re-rendering

Explanation: Layouts remain mounted across navigation within their scope; only the inner page.tsx content changes, preserving the layout's own state.

5. How many root layouts can a single Next.js App Router project have?

  1. Zero
  2. Exactly one
  3. Unlimited
  4. One per page

Answer: B. Exactly one

Explanation: There must be exactly one root layout at app/layout.tsx, since it uniquely provides the required <html> and <body> tags for the whole application.

Common Mistakes to Avoid

  • Forgetting to include <html> and <body> tags in the root layout, causing invalid HTML structure.
  • Manually passing a children prop into a layout component instead of letting Next.js supply it automatically.
  • Duplicating a navbar inside every page.tsx instead of placing it once in a shared layout.tsx.
  • Expecting a nested layout to affect routes outside its own folder, when it only applies to its own subtree.
  • Assuming a layout re-fetches data or resets state on every navigation, when in fact it persists across navigation within its scope.

Interview Notes

  • The root layout at app/layout.tsx is mandatory and must include <html> and <body> tags.
  • page.tsx = unique content per route; layout.tsx = shared UI wrapping a page and its nested routes.
  • The children prop is automatically supplied to a layout, representing nested page or layout content.
  • Nested layouts apply only to routes within their own folder and subfolders, not the whole app.
  • Layouts persist across navigation within their scope, avoiding unnecessary re-renders of shared UI.

Key Takeaways

  • page.tsx and layout.tsx together let you share UI without duplicating it across every route.
  • The mandatory root layout is where global concerns — HTML structure, global styles, app-wide navigation — belong.
  • Nested layouts scale this same idea to specific sections of a site, like a dashboard or checkout flow.
  • Layout persistence across navigation is a meaningful performance and UX advantage baked into the App Router's design.

Summary

In the Next.js App Router, page.tsx and layout.tsx divide responsibilities cleanly: page.tsx defines unique content for a specific URL, while layout.tsx defines shared UI wrapping a page and any nested routes beneath it. Every project requires exactly one root layout at app/layout.tsx, which must contain the <html> and <body> tags and wraps the entire application. Additional nested layouts can be added inside any subfolder to apply section-specific shared UI, such as a dashboard sidebar. Layouts receive nested content automatically via the children prop and, critically, persist across navigation within their scope rather than re-rendering, preserving UI state and avoiding redundant work.

Frequently Asked Questions

A page (page.tsx) defines the unique content for one specific route. A layout (layout.tsx) defines shared UI, like a navbar or sidebar, that wraps a page and any of its nested routes without being duplicated on every page.

Yes. Every App Router project must have exactly one root layout at app/layout.tsx, and it must include the <html> and <body> tags since it's the outermost wrapper for the whole application.

Yes. Beyond the required root layout, you can add nested layouts inside any subfolder of app/ to apply additional shared UI to just that section of your site, such as a dashboard-specific sidebar layout.

No. Layouts persist across navigation within their scope. Only the page.tsx content nested inside changes; the layout itself and any state it holds remain mounted.

children is a special prop automatically passed to a layout, representing whatever page or nested layout should render inside it. You render it using {children} at the appropriate position in your layout's JSX.

No, and it shouldn't try to. Only the root layout should contain <html> and <body> tags; nested layouts return regular JSX elements like <div> or <section> that render inside the root layout's <body>.

It simply renders directly inside whichever layout is closest above it in the folder hierarchy — ultimately falling back to the root layout if no nested layouts exist for that route's path.

Yes, this is a very common pattern. You can create a nested layout.tsx inside a folder like app/dashboard/ that applies sidebar and app-specific navigation only to routes within that folder, while public routes outside it use only the root layout.

Not negatively — each page still generates its own complete HTML, including layout markup, on first load or server render. Layout persistence is a client-side navigation optimization that improves user experience without affecting how content is initially delivered to crawlers.

Yes. A layout can be an async Server Component that fetches its own data, such as a user's profile for a sidebar, independently of whatever data the nested page fetches for its own content.