layout.js

Макет (layout) — это пользовательский интерфейс, который является общим для нескольких маршрутов.

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return <section>{children}</section>
}
export default function DashboardLayout({ children }) {
  return <section>{children}</section>
}

Корневой макет (root layout) — это самый верхний макет в корневой директории app. Он используется для определения тегов <html> и <body>, а также других общих элементов интерфейса.

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

Пропсы

children (обязательный)

Компоненты макета должны принимать и использовать проп children. Во время рендеринга children будет заполнен сегментами маршрута, которые оборачивает макет. В основном это будет компонент дочернего Макета (если он существует) или Страницы, но также могут быть и другие специальные файлы, такие как Загрузка или Ошибка, когда это применимо.

params (опциональный)

Объект динамических параметров маршрута от корневого сегмента до данного макета.

ПримерURLparams
app/dashboard/[team]/layout.js/dashboard/1{ team: '1' }
app/shop/[tag]/[item]/layout.js/shop/1/2{ tag: '1', item: '2' }
app/blog/[...slug]/layout.js/blog/1/2{ slug: ['1', '2'] }

Пример:

export default function ShopLayout({
  children,
  params,
}: {
  children: React.ReactNode
  params: {
    tag: string
    item: string
  }
}) {
  // URL -> /shop/shoes/nike-air-max-97
  // `params` -> { tag: 'shoes', item: 'nike-air-max-97' }
  return <section>{children}</section>
}
export default function ShopLayout({ children, params }) {
  // URL -> /shop/shoes/nike-air-max-97
  // `params` -> { tag: 'shoes', item: 'nike-air-max-97' }
  return <section>{children}</section>
}

Полезно знать

Макеты не получают searchParams

В отличие от Страниц, компоненты макета не получают проп searchParams. Это связано с тем, что общий макет не перерендеривается во время навигации, что может привести к устаревшим searchParams между переходами.

При использовании клиентской навигации Next.js автоматически рендерит только часть страницы ниже общего макета между двумя маршрутами.

Например, в следующей структуре директорий dashboard/layout.tsx является общим макетом для /dashboard/settings и /dashboard/analytics:

Структура файлов, показывающая папку dashboard с вложенным файлом layout.tsx, а также папки settings и analytics с их собственными страницами

При переходе с /dashboard/settings на /dashboard/analytics, page.tsx в /dashboard/analytics будет перерендерен на сервере, а dashboard/layout.tsx не будет перерендерен, так как это общий интерфейс для обоих маршрутов.

Эта оптимизация производительности позволяет ускорить навигацию между страницами, которые используют общий макет, так как выполняется только получение данных и рендеринг страницы, а не всего маршрута, который может включать общие макеты с собственными запросами данных.

Поскольку dashboard/layout.tsx не перерендеривается, проп searchParams в серверном компоненте макета может стать устаревшим после навигации.

  • Вместо этого используйте проп searchParams Страницы или хук useSearchParams в клиентском компоненте, который перерендеривается на клиенте с актуальными searchParams.

Корневые макеты

  • В директории app обязательно должен быть корневой app/layout.js.
  • Корневой макет обязан определять теги <html> и <body>.
    • Не следует вручную добавлять теги <head>, такие как <title> и <meta>, в корневые макеты. Вместо этого используйте API Metadata, который автоматически обрабатывает сложные требования, такие как потоковая передача и дедупликация элементов <head>.
  • Вы можете использовать группы маршрутов для создания нескольких корневых макетов.
    • Навигация между несколькими корневыми макетами вызовет полную перезагрузку страницы (в отличие от клиентской навигации). Например, переход с /cart, который использует app/(shop)/layout.js, на /blog, который использует app/(marketing)/layout.js, вызовет полную перезагрузку страницы. Это применяется только к нескольким корневым макетам.

История версий

ВерсияИзменения
v13.0.0Добавлен layout.