Урок 08

Route Groups и организация

Группы маршрутов (name) не попадают в URL. Используются для организации кода.

Базовый пример

app/
├── (marketing)/
│   ├── about/page.tsx       → /about
│   ├── pricing/page.tsx     → /pricing
│   └── contact/page.tsx     → /contact
└── (shop)/
    ├── products/page.tsx    → /products
    └── cart/page.tsx        → /cart

URL не содержит marketing или shop.

Зачем группы

  • Разные layouts для разных секций
  • Логическая организация кода
  • Разные метаданные для групп
  • Разные middleware (через matcher)

Разные layouts

app/
├── (marketing)/
│   ├── layout.tsx           ← marketing layout
│   ├── page.tsx             → /
│   └── about/page.tsx       → /about
└── (app)/
    ├── layout.tsx           ← app layout
    ├── dashboard/page.tsx   → /dashboard
    └── settings/page.tsx    → /settings

/ и /about получат marketing layout, /dashboard — app layout.

Несколько root layouts

Можно создать разные root layouts для разных групп:

app/
├── (marketing)/
│   ├── layout.tsx           ← со своим <html>
│   └── page.tsx
└── (app)/
    ├── layout.tsx           ← со своим <html>
    └── dashboard/page.tsx

Если в группе есть свой layout.tsx с <html> — root layout app/layout.tsx не нужен.

Организация по фичам

app/
├── (auth)/
│   ├── login/page.tsx
│   └── register/page.tsx
├── (dashboard)/
│   ├── layout.tsx
│   ├── dashboard/page.tsx
│   └── settings/page.tsx
└── (public)/
    ├── page.tsx
    └── about/page.tsx

Каждая группа — своя логика.

Конфликты URL

Нельзя, чтобы два маршрута совпадали:

app/
├── (a)/about/page.tsx       → /about
└── (b)/about/page.tsx       → /about — конфликт

Next.js выдаст ошибку при сборке.

Приватные папки vs группы

  • _folder — исключается из роутинга полностью
  • (folder) — не в URL, но маршруты внутри работают
app/
├── _components/Button.tsx   → просто файл
├── (auth)/login/page.tsx    → /login
└── about/page.tsx           → /about

Колокация

Компоненты, хуки, утилиты можно держать рядом с использованием:

app/
├── posts/
│   ├── page.tsx
│   ├── _components/
│   │   ├── PostCard.tsx
│   │   └── PostList.tsx
│   ├── _lib/
│   │   └── utils.ts
│   └── [id]/
│       └── page.tsx

Папка _components не станет маршрутом.

Альтернатива: папка components

Вне app/:

src/
├── app/
│   └── posts/page.tsx
├── components/
│   └── PostCard.tsx
└── lib/
    └── utils.ts

Импорт через алиас @/components/PostCard.

Когда что

  • Колокация в app/_folder — если компонент используется только в одном месте
  • Общая папка components/ — если используется в разных местах
  • Группы (name) — для разных layouts и логической организации

Практика

app/
├── (auth)/
│   ├── layout.tsx
│   ├── login/page.tsx
│   └── register/page.tsx
├── (dashboard)/
│   ├── layout.tsx
│   ├── dashboard/page.tsx
│   ├── settings/page.tsx
│   └── _components/
│       └── StatCard.tsx
├── (marketing)/
│   ├── layout.tsx
│   ├── page.tsx
│   ├── about/page.tsx
│   └── pricing/page.tsx
├── api/
│   └── posts/route.ts
└── layout.tsx

Чисто, логично, каждый раздел со своим layout.

Итоги

  • (name) — группа без URL
  • Разные layouts для групп
  • Несколько root layouts возможны
  • Нельзя дублировать URL
  • Колокация через _folder
  • Общая папка для переиспользуемых