Next.js

Lesson 02

Layout and page boundaries

Keep shared chrome in layouts and route-specific data in pages.

Good Code

app/dashboard/layout.tsx
import Link from "next/link";

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  // The layout owns shared navigation while child pages supply route content.
  return (
    <section>
      <nav aria-label="Dashboard">
        <Link href="/dashboard">Overview</Link>
        <Link href="/dashboard/reviews">Reviews</Link>
      </nav>
      <main>{children}</main>
    </section>
  );
}

Bad Code

app/dashboard/layout.tsx
import { getLatestReviews } from "@/lib/reviews";

export default async function DashboardLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  // Fetching leaf-page data here blocks child routes that may not need it.
  const reviews = await getLatestReviews();

  return (
    <section>
      <aside>{reviews.length} reviews need attention</aside>
      <main>{children}</main>
    </section>
  );
}

Review Notes

What to review

Good Code

The good version uses the layout for persistent navigation and places route-specific content in the child page.

Bad Code

The bad version fetches leaf-page data inside the layout, so every child route can be blocked by data it may not need.

Takeaways

  • Layouts should hold persistent UI while pages own the leaf route content.