Макеты и корневой макет
Макет (layout) — компонент, который оборачивает страницы и содержит общие для них части: шапку, меню, подвал. Макет описывают один раз, и Next.js сам вставляет в него нужную страницу.
Корневой макет
Файл app/layout.tsx уже создан утилитой. Это корневой макет: он обязателен и оборачивает все страницы сайта. Упростим его:
// app/layout.tsx
import './globals.css';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ru">
<body>
<header>Мой блог</header>
{children}
<footer>© 2025 Анна</footer>
</body>
</html>
);
}В свойство children Next.js передаёт текущую страницу. Откройте / и /about — шапка и подвал есть на обеих страницах, меняется только середина.
Почему здесь html и body
Только корневой макет содержит теги html и body — Next.js не добавляет их сам. Атрибут lang подсказывает браузеру и поисковикам язык страницы.
Макет раздела
Макет можно положить в любую папку. Он оборачивает страницы этой папки и всех вложенных. Создайте файл app/posts/layout.tsx:
// app/posts/layout.tsx
export default function PostsLayout({ children }: { children: React.ReactNode }) {
return (
<section>
<aside>Рубрики: React, Next.js, CSS</aside>
{children}
</section>
);
}Теперь на /posts и на всех адресах внутри /posts/... появится блок с рубриками, а на главной его нет.
Вложенность макетов
Макеты вкладываются друг в друга по папкам:
| Адрес | Что оборачивает страницу |
|---|---|
/ | app/layout.tsx |
/about | app/layout.tsx |
/posts | app/layout.tsx, затем app/posts/layout.tsx |
Макет сохраняется при переходах
При переходе между страницами одного раздела макет не создаётся заново: его состояние, например открытое меню или текст в поле поиска, сохраняется. Перерисовывается только страница.
Частая ошибка
Добавить теги html и body во вложенный макет. Внутри одного body окажется второй, браузер получит неверный HTML, а React выдаст ошибку гидратации. Эти теги пишутся только в app/layout.tsx, остальные макеты возвращают обычную разметку вроде section или div.