Страницы и макеты
Перед продолжением рекомендуем ознакомиться со страницами Основы маршрутизации и Определение маршрутов.
Специальные файлы layout.js, page.js и template.js позволяют создавать пользовательский интерфейс для маршрута. Эта страница поможет вам разобраться, как и когда использовать эти специальные файлы.
Страницы
Страница — это пользовательский интерфейс, уникальный для маршрута. Вы можете определить страницу по умолчанию, экспортировав компонент из файла page.js.
Например, чтобы создать страницу index, добавьте файл page.js в директорию app:


// `app/page.tsx` is the UI for the `/` URL
export default function Page() {
return <h1>Hello, Home page!</h1>
}Затем, чтобы создать дополнительные страницы, создайте новую папку и добавьте в неё файл page.js. Например, чтобы создать страницу для маршрута /dashboard, создайте новую папку под названием dashboard и добавьте в неё файл page.js:
// `app/dashboard/page.tsx` is the UI for the `/dashboard` URL
export default function Page() {
return <h1>Hello, Dashboard Page!</h1>
}Важно знать:
- Для страниц можно использовать расширения файлов
.js,.jsx, или.tsx.- Страница всегда является листом поддерева маршрута.
- Файл
page.jsнеобходим для публичного доступа к сегменту маршрута.- Страницы по умолчанию являются Компонентами сервера, но могут быть настроены на Компонент клиента.
- Страницы могут извлекать данные. Для получения дополнительной информации см. раздел Загрузка данных.
Макеты
Макет — это пользовательский интерфейс, общий для нескольких маршрутов. При переходе по ссылкам макеты сохраняют состояние, остаются интерактивными и не перерисовываются. Макеты также могут быть вложены.
Вы можете определить макет по умолчанию, экспортировав компонент React из файла layout.js. Компонент должен принимать свойство children, которое будет заполнено дочерним макетом (если он существует) или страницей во время отрисовки.
Например, макет будет общим для страниц /dashboard и /dashboard/settings:


export default function DashboardLayout({
children, // will be a page or nested layout
}: {
children: React.ReactNode
}) {
return (
<section>
{/* Include shared UI here e.g. a header or sidebar */}
<nav></nav>
{children}
</section>
)
}Корневой макет (обязателен)
Корневой макет определяется на верхнем уровне директории app и применяется ко всем маршрутам. Этот макет обязателен и должен содержать теги html и body, что позволит вам изменять исходный HTML, возвращаемый сервером.
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
{/* Layout UI */}
<main>{children}</main>
</body>
</html>
)
}Вложение макетов
По умолчанию макеты в иерархии папок вложены, что означает, что они обертывают дочерние макеты через свойство children. Вы можете вложить макеты, добавив layout.js в определенные сегменты маршрута (папки).
Например, чтобы создать макет для маршрута /dashboard, добавьте новый файл layout.js в папку dashboard:


export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}Если вы объедините два вышеприведённых макета, корневой макет (app/layout.js) будет обертывать макет панели инструментов (app/dashboard/layout.js), который будет обертывать сегменты маршрутов внутри app/dashboard/*.
Два макета будут вложены следующим образом:


Важно знать:
- Для макетов можно использовать расширения файлов
.js,.jsx, или.tsx.- Только корневой макет может содержать теги
<html>и<body>.- Когда файл
layout.jsиpage.jsопределены в одной папке, макет будет обертывать страницу.- Макеты по умолчанию являются Компонентами сервера, но могут быть настроены на Компонент клиента.
- Макеты могут извлекать данные. Для получения дополнительной информации см. раздел Загрузка данных.
- Передача данных между родительским макетом и его дочерними элементами невозможна. Однако вы можете загрузить одни и те же данные в маршрут более одного раза, и React автоматически исключит дублирующиеся запросы, не влияя на производительность.
- Макеты не имеют доступа к сегментам маршрутов ниже себя. Чтобы получить доступ ко всем сегментам маршрутов, вы можете использовать
useSelectedLayoutSegmentилиuseSelectedLayoutSegmentsв компоненте клиента.- Вы можете использовать Группы маршрутов для выбора определенных сегментов маршрутов для общих макетов.
- Вы можете использовать Группы маршрутов для создания нескольких корневых макетов. См. пример здесь.
- Миграция из директории
pages: Корневой макет заменяет файлы_app.jsи_document.js. См. руководство по миграции.
Шаблоны
Шаблоны похожи на макеты тем, что они обертывают каждый дочерний макет или страницу. В отличие от макетов, которые сохраняются при переходе по маршрутам и сохраняют состояние, шаблоны создают новый экземпляр для каждого из своих дочерних элементов при переходе. Это означает, что при переходе пользователя между маршрутами, которые используют один и тот же шаблон, компонент монтируется как новый экземпляр, элементы DOM пересоздаются, состояние не сохраняется, и эффекты пересинхронизируются.
В некоторых случаях вам могут потребоваться эти специфические поведения, и шаблоны будут более подходящим вариантом, чем макеты. Например:
- Функции, которые зависят от
useEffect(например, регистрация просмотров страниц) иuseState(например, форма обратной связи для каждой страницы). - Для изменения поведения фреймворка по умолчанию. Например, границы отложенной загрузки внутри макетов показывают резервный вариант только в первый раз, когда макет загружается, а не при переходе между страницами. В шаблонах резервный вариант отображается при каждом переходе.
Шаблон можно определить, экспортировав компонент React по умолчанию из файла template.js. Компонент должен принимать свойство children.


export default function Template({ children }: { children: React.ReactNode }) {
return <div>{children}</div>
}С точки зрения вложения, template.js отображается между макетом и его дочерними элементами. Вот упрощенный вывод:
<Layout>
{/* Note that the template is given a unique key. */}
<Template key={routeParam}>{children}</Template>
</Layout>Метаданные
В директории app вы можете изменить элементы HTML <head>, такие как title и meta, с помощью API метаданных.
Метаданные можно определить, экспортировав объект metadata или функцию generateMetadata в файле layout.js или page.js.
import { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Next.js',
}
export default function Page() {
return '...'
}Важно знать: Не следует вручную добавлять теги
<head>, такие как<title>и<meta>, в корневые макеты. Вместо этого вы должны использовать API метаданных, который автоматически обрабатывает сложные требования, такие как потоковая передача и исключение дубликатов<head>элементов.
Узнайте больше о доступных вариантах метаданных в справочнике API
© 2024 Vercel, Inc.
Licensed under the MIT License.
https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts