Пошук уроків, статей та іншого контенту
Створите базову сторінку та спільний каркас застосунку за допомогою файлів layout.tsx і page.tsx.
layout.tsx і page.tsxУ Next.js з App Router структура папки app визначає структуру застосунку та його маршрути.
Два основні файли:
page.tsx описує вміст конкретної сторінки;
layout.tsx описує спільний каркас сторінки та обгортає її вміст.
Наприклад:
app/
├── layout.tsx
└── page.tsxУ цьому випадку:
app/page.tsx відповідає за маршрут /;
app/layout.tsx є спільним кореневим каркасом застосунку.
page.tsxФайл page.tsx визначає UI для певного маршруту.
Найпростіша головна сторінка:
export default function HomePage() {
return (
<main>
<h1>Головна сторінка</h1>
<p>Ласкаво просимо до нашого застосунку.</p>
</main>
);
}Експортована за замовчуванням функція є React-компонентом. Next.js відображає результат його роботи в браузері.
Оскільки файл розташований за адресою app/page.tsx, сторінка доступна за маршрутом:
/Тобто після запуску застосунку її можна відкрити за адресою http://localhost:3000.
layout.tsxlayout.tsx містить спільну частину інтерфейсу. Такий компонент може включати:
кореневі HTML-теги;
навігацію;
шапку;
підвал;
спільні стилі або обгортки.
Кореневий layout повинен приймати проп children. У нього Next.js передає вміст поточної сторінки.
Приклад:
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Мій застосунок',
description: 'Навчальний застосунок на Next.js',
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="uk">
<body>
<header>
<nav>
<a href="/">Головна</a>
</nav>
</header>
{children}
<footer>
<p>© 2026 Мій застосунок</p>
</footer>
</body>
</html>
);
}Вираз {children} — це місце, у яке буде вставлено вміст page.tsx.
У результаті браузер отримає приблизно таку структуру:
<html lang="uk">
<body>
<header>
<nav>
<a href="/">Головна</a>
</nav>
</header>
<main>
<h1>Головна сторінка</h1>
<p>Ласкаво просимо до нашого застосунку.</p>
</main>
<footer>
<p>© 2026 Мій застосунок</p>
</footer>
</body>
</html>Для створення нового Next.js-застосунку з TypeScript та App Router можна виконати команду:
npx create-next-app@latest my-next-appПід час налаштування виберіть:
TypeScript — Yes;
App Router — Yes;
інші параметри — за потреби.
Після створення перейдіть до папки проєкту:
cd my-next-app
npm run devТепер застосунок доступний за адресою http://localhost:3000.
Структура файлів:
app/
├── layout.tsx
└── page.tsxapp/layout.tsximport type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Книжкова полиця',
description: 'Простий застосунок зі списком книжок',
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="uk">
<body>
<header>
<nav>
<a href="/">Книжкова полиця</a>
</nav>
</header>
{children}
<footer>
<p>Навчальний проєкт на Next.js</p>
</footer>
</body>
</html>
);
}app/page.tsxconst books = [
'Кобзар',
'Тигролови',
'Місто',
];
export default function HomePage() {
return (
<main>
<h1>Моя книжкова полиця</h1>
<p>Книги, які я планую прочитати:</p>
<ul>
{books.map((book) => (
<li key={book}>{book}</li>
))}
</ul>
</main>
);
}У цьому прикладі:
layout.tsx додає навігацію та підвал;
page.tsx відображає заголовок і список книжок;
масив books використовується для створення елементів списку;
children у layout містить результат роботи HomePage.
Next.js об'єднує layout і page під час формування сторінки:
RootLayout(
children = HomePage()
)Тому вміст page.tsx не замінює layout.tsx, а вставляється в нього.
Це дозволяє не дублювати однакову розмітку на кожній сторінці. Наприклад, навігацію достатньо написати один раз у layout.tsx.
Папки всередині app створюють додаткові маршрути. Наприклад:
app/
├── layout.tsx
├── page.tsx
└── about/
└── page.tsxФайл app/about/page.tsx відповідає за маршрут:
/aboutЙого вміст може бути таким:
export default function AboutPage() {
return (
<main>
<h1>Про застосунок</h1>
<p>Це сторінка з інформацією про наш застосунок.</p>
</main>
);
}Кореневий app/layout.tsx також буде застосований до цієї сторінки. Отже, навігація та підвал залишаться спільними для / і /about.
Для переходу між цими сторінками можна тимчасово використати звичайні HTML-посилання:
<nav>
<a href="/">Головна</a>
<a href="/about">Про застосунок</a>
</nav>layout.tsx і page.tsx| Файл | Призначення | |---|---| | page.tsx | Вміст конкретного маршруту | | layout.tsx | Спільний каркас для сторінки або групи сторінок |
page.tsx зазвичай містить основний вміст сторінки:
export default function Page() {
return <h1>Заголовок сторінки</h1>;
}layout.tsx містить обгортку та {children}:
export default function Layout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<div>
<header>Спільна шапка</header>
{children}
</div>
);
}childrenLayout повинен приймати children і відображати його:
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return <body>{children}</body>;
}Якщо не додати {children}, вміст page.tsx не буде показано.
Для головного маршруту файли повинні розташовуватися так:
app/
├── layout.tsx
└── page.tsxФайл page.tsx за межами папки app не створить маршрут App Router.
Next.js очікує, що page.tsx і layout.tsx матимуть компонент, експортований через export default:
export default function Page() {
return <h1>Сторінка</h1>;
}Не потрібно додавати однакову навігацію в кожен page.tsx. Якщо елемент має бути на всіх сторінках, розмістіть його в layout.tsx.
Кореневий layout має містити html і body:
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="uk">
<body>{children}</body>
</html>
);
}page.tsx визначає вміст конкретного маршруту.
app/page.tsx відповідає за головний маршрут /.
layout.tsx містить спільний каркас сторінки.
Вміст поточного маршруту передається в layout через проп children.
Кореневий layout зазвичай містить html, body, навігацію та підвал.
Папки всередині app разом із page.tsx створюють вкладені маршрути.
Спільну розмітку потрібно зберігати в layout, щоб не дублювати її в сторінках.