Skip to main content

Overview

Next.js App Router provides powerful layout features for creating consistent UI patterns. Understanding layouts is crucial for building maintainable applications.

What are Layouts?

Layouts are shared UI that persists across route changes and maintains state during navigation.

Key Characteristics

Layout Characteristics

  • Shared UI across multiple pages
  • Maintains state during navigation
  • Renders once and stays mounted
  • Perfect for navigation, headers, footers

Layout Benefits

  • Consistent user experience
  • Performance optimization
  • State preservation
  • Reduced re-rendering

Root Layout

The root layout wraps all pages and is required in every Next.js app.
// app/layout.tsx
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "My App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en" className={inter.className}>
      <body>
        <header>
          <nav>
            <a href="/">Home</a>
            <a href="/about">About</a>
            <a href="/contact">Contact</a>
          </nav>
        </header>
        <main>{children}</main>
        <footer>
          <p>&copy; 2024 My App. All rights reserved.</p>
        </footer>
      </body>
    </html>
  );
}

Nested Layouts

Layouts can be nested to create hierarchical UI structures.
// app/dashboard/layout.tsx
import Sidebar from "@/components/Sidebar";

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="dashboard-layout">
      <Sidebar />
      <div className="dashboard-content">{children}</div>
    </div>
  );
}

Layout Hierarchy

app/
├── layout.tsx              # Root layout (wraps everything)
├── dashboard/
│   ├── layout.tsx          # Dashboard layout (wraps dashboard pages)
│   ├── page.tsx            # /dashboard
│   └── settings/
│       ├── layout.tsx      # Settings layout (wraps settings pages)
│       └── page.tsx        # /dashboard/settings

Basic Layout Patterns

Simple Layout with Navigation

// app/layout.tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <div className="min-h-screen flex flex-col">
          <header className="bg-white shadow-sm">
            <nav className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
              <div className="flex justify-between items-center">
                <div className="flex space-x-8">
                  <a href="/" className="text-gray-900">
                    Home
                  </a>
                  <a href="/about" className="text-gray-900">
                    About
                  </a>
                  <a href="/contact" className="text-gray-900">
                    Contact
                  </a>
                </div>
              </div>
            </nav>
          </header>

          <main className="flex-1">{children}</main>

          <footer className="bg-gray-800 text-white">
            <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
              <p>&copy; 2024 My App. All rights reserved.</p>
            </div>
          </footer>
        </div>
      </body>
    </html>
  );
}

Dashboard Layout

// app/dashboard/layout.tsx
import Sidebar from "@/components/Sidebar";
import Header from "@/components/Header";

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="dashboard-layout">
      <Sidebar />
      <div className="dashboard-main">
        <Header />
        <div className="dashboard-content">{children}</div>
      </div>
    </div>
  );
}

Layout with Metadata

// app/blog/layout.tsx
import { Metadata } from "next";

export const metadata: Metadata = {
  title: "Blog - My App",
  description: "Read our latest blog posts",
};

export default function BlogLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="blog-layout">
      <aside className="blog-sidebar">
        <h2>Categories</h2>
        {/* Category links */}
      </aside>
      <main className="blog-main">{children}</main>
    </div>
  );
}

Best Practices for Module 1

Layout Design

  1. Keep Layouts Simple: Focus on shared UI elements and avoid complex logic
  2. Use Nested Layouts: Create hierarchical layouts for better organization
  3. Optimize Performance: Minimize re-renders and use proper state management
  4. Handle Loading States: Provide appropriate loading states
Key Takeaway: Layouts are powerful tools for creating consistent UI patterns. Use them for shared UI that should persist across routes, like navigation, headers, and footers.