Route Groups & Multiple Root Layouts

Use parenthesized groups to give sections their own root layout, split marketing from app, and opt segments into a shared layout without touching the URL.

Route groups — folders wrapped in (parentheses) — are more powerful than the 'organize files' one-liner suggests. At senior level they are how you carve an app into sections with genuinely different chrome.

Multiple root layouts

If you put a layout.tsx with <html> and <body> inside each top-level group and remove the single shared root, you get two independent document shells — say a lean marketing site and a heavyweight authenticated app — that share nothing but the same deployment.

app/
  (marketing)/
    layout.tsx      // its own , minimal JS
    page.tsx        // -> /
    pricing/page.tsx
  (app)/
    layout.tsx      // its own , app shell + providers
    dashboard/page.tsx

The trade-off to know

Because the two roots are separate documents, navigating between them is a full page load, not a soft transition — the whole tree unmounts. That is usually what you want at a marketing/app boundary, but it means you should not scatter groups with sibling root layouts across a flow users cross constantly.

Opting a subset into a layout

You can also nest a group purely to wrap some siblings in an extra layout while leaving their URLs flat: app/(admin)/settings/page.tsx still serves /settings, but now shares (admin)/layout.tsx.

Example

Example · typescript
// app/(marketing)/layout.tsx — a full, standalone root layout
export default function MarketingLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className="marketing">
        <SiteNav />
        {children}
        <SiteFooter />
      </body>
    </html>
  );
}

// app/(app)/layout.tsx — a DIFFERENT root for the authenticated app
export default function AppLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className="app-shell">
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

When to use it

  • A SaaS product separates the (marketing) public site from the (app) authenticated dashboard, each with a different root layout.
  • A team organises routes into (auth), (dashboard), and (marketing) groups so each section has its own nav, fonts, and providers.
  • An enterprise app applies a different analytics provider to (admin) routes versus (public) routes by using separate group layouts.

More examples

Two root layouts via groups

Each group defines its own layout.tsx at the same nesting level, creating two separate root layout trees.

Example · bash
app/
├── (marketing)/
│   ├── layout.tsx   # marketing root layout (no auth)
│   ├── page.tsx     # → /
│   └── about/page.tsx
└── (app)/
    ├── layout.tsx   # app root layout (with auth)
    └── dashboard/page.tsx

Group layout with providers

The (app) layout wraps its children in AuthProvider and SidebarNav without affecting the marketing group.

Example · ts
// app/(app)/layout.tsx
import { AuthProvider } from '@/components/AuthProvider';
import { SidebarNav } from '@/components/SidebarNav';

export default function AppLayout({ children }: { children: React.ReactNode }) {
  return (
    <AuthProvider>
      <div className="flex">
        <SidebarNav />
        <main>{children}</main>
      </div>
    </AuthProvider>
  );
}

Shared layout without URL segment

The (shop) group shares a checkout-aware layout across /products and /cart without adding /shop to the URL.

Example · bash
app/
└── (shop)/
    ├── layout.tsx          # shared shop layout
    ├── products/page.tsx   # → /products
    └── cart/page.tsx       # → /cart

Discussion

  • Be the first to comment on this lesson.
Route Groups & Multiple Root Layouts — Next.js | SoundsCode