Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Макеты и корневой макет

Макет (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
/aboutapp/layout.tsx
/postsapp/layout.tsx, затем app/posts/layout.tsx

Макет сохраняется при переходах

При переходе между страницами одного раздела макет не создаётся заново: его состояние, например открытое меню или текст в поле поиска, сохраняется. Перерисовывается только страница.

Частая ошибка

Добавить теги html и body во вложенный макет. Внутри одного body окажется второй, браузер получит неверный HTML, а React выдаст ошибку гидратации. Эти теги пишутся только в app/layout.tsx, остальные макеты возвращают обычную разметку вроде section или div.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.