Пошук уроків, статей та іншого контенту
Як структура папок у app/ визначає URL-адреси застосунку, та роль спеціальних файлів.
У App Router кожна папка всередині app/ відповідає сегменту URL-адреси, а файл page.tsx усередині папки — це те, що реально рендериться за цією адресою. Папка без page.tsx не стає доступним маршрутом, навіть якщо містить інші файли — вона просто організовує структуру.
app/
├─ page.tsx → /
├─ about/
│ └─ page.tsx → /about
└─ blog/
├─ page.tsx → /blog
└─ [slug]/
└─ page.tsx → /blog/будь-який-слаг (динамічний сегмент)Папка в квадратних дужках — [slug] — створює динамічний сегмент маршруту: значення з URL стає доступним компоненту сторінки через параметр params. Починаючи з Next.js 15, params — це Promise, тому його потрібно await:
// app/blog/[slug]/page.tsx
export default async function BlogPostPage({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
const post = await getPostBySlug(slug);
return <article>{post.title}</article>;
}layout.tsx обгортає всі сторінки й вкладені маршрути в межах своєї папки — типово для шапки сайту, бічної панелі навігації, футера. Кореневий layout.tsx (app/layout.tsx) обов'язковий і має містити теги <html> і <body> — саме тут, а не в page.tsx.
// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="uk">
<body>
<Header />
{children}
<Footer />
</body>
</html>
);
}Layout не перерендерюється при навігації між сторінками всередині нього — його стан (наприклад, розкрите мобільне меню) зберігається, коли користувач переходить із однієї дочірньої сторінки на іншу. Це і оптимізація продуктивності, і привід не класти в layout логіку, яка мала б оновлюватись на кожну навігацію.
Папка в круглих дужках — (marketing) — групує маршрути логічно (наприклад, під спільний layout), але сама не додається до URL:
app/
└─ (marketing)/
├─ layout.tsx → спільний layout лише для сторінок нижче
├─ about/page.tsx → /about (НЕ /marketing/about)
└─ pricing/page.tsx → /pricingloading.tsx — автоматичний UI завантаження, поки асинхронний page.tsx у цій папці ще виконується.
error.tsx — межа обробки помилок (error boundary) для цього сегмента й усіх вкладених.
not-found.tsx — власний вигляд сторінки 404 для цього сегмента.
Створити папку з компонентами, але забути page.tsx усередині — сегмент не стане доступним маршрутом, навіть якщо всі інші файли на місці.
Звертатись до params як до звичайного об'єкта без await — з Next.js 15 це Promise, і пряме читання params.slug без await призведе до помилки типів (і в рантаймі — до неправильної поведінки).
Класти логіку, що має оновлюватись при кожній навігації, у layout.tsx — layout не перерендерюється між дочірніми сторінками, тому такий код виконається лише один раз.
У App Router структура папок app/ безпосередньо визначає URL-адреси: page.tsx робить сегмент доступним маршрутом, [slug] створює динамічний сегмент (з асинхронним params починаючи з Next.js 15), layout.tsx — спільну, не перерендерювану між навігаціями оболонку, а group-папки в дужках організовують структуру без впливу на URL.