SyntaxStudy
Sign Up
Next.js Layouts, Templates, and Nested Routing
Next.js Beginner 1 min read

Layouts, Templates, and Nested Routing

Layouts in Next.js are components that wrap a route segment and its children. Defined in layout.tsx, they persist across navigations — the layout component is not re-rendered when navigating between child routes, which preserves state and avoids expensive re-mounts. The root layout at app/layout.tsx is required and must include html and body tags because Next.js does not add them automatically. Layouts can be nested. A layout at app/dashboard/layout.tsx wraps only the dashboard routes while sharing the root layout above it. This creates a natural hierarchy that maps the layout tree to the URL tree. Each layout receives a children prop which is the rendered content of the next segment in the route tree. Templates are similar to layouts but create a new instance on every navigation, which is useful when you need per-route state reset or entry animations. They are defined in template.tsx. Route groups (folders with parentheses like (auth)) allow you to apply different layouts to logically related routes without changing their URL, which is perfect for separate authenticated and guest layouts.
Example
// app/dashboard/layout.tsx
// Wraps all routes under /dashboard/**

import Sidebar from '@/components/Sidebar';
import TopBar from '@/components/TopBar';

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="flex h-screen">
      <Sidebar />
      <div className="flex-1 flex flex-col">
        <TopBar />
        <main className="flex-1 overflow-y-auto p-6">
          {children}
        </main>
      </div>
    </div>
  );
}

// app/(auth)/layout.tsx  — route group layout for /login, /register
// URL is still /login and /register (no "(auth)" in path)
export default function AuthLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="min-h-screen flex items-center justify-center bg-gray-50">
      <div className="w-full max-w-md bg-white rounded-lg shadow p-8">
        {children}
      </div>
    </div>
  );
}