- Удалён shiki (9.5→0 МБ), создан regex-токенизатор для html/css/xml - CLI переведён с аргументов на конфиг-файл svg-sprites.config.ts - Превью переработано: React-приложение вместо инлайн HTML - Добавлен футер с названием пакета и ссылкой на репозиторий - Исправлена загрузка dev-data.js для Vite 8 - Футер прижат к низу, содержимое центрировано
2.7 KiB
2.7 KiB
title, scope, keywords, when
| title | scope | keywords | when | |||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Файлы роутинга | applied |
|
Работа с файлами роутинга Next.js App Router: page, layout, error, not-found |
Файлы роутинга
Правила для специальных файлов App Router (page.tsx, layout.tsx, error.tsx, not-found.tsx и др.) — чем наш подход отличается от дефолтного.
Что нужно знать
Страница в проекте — это два файла: экран в src/screens/ (вся логика, стили, зависимости) и page.tsx в src/app/ (точка входа для роутинга Next.js). Экран генерируется из шаблона, page.tsx создаётся вручную.
Организация
page.tsx— тонкий файл: толькоmetadataи рендер экрана. Логика, стили и зависимости живут в экране, не вpage.tsx.error.tsxиnot-found.tsxделегируют разметку экранам по тому же принципу.layout.tsx— точка подключения провайдеров и глобальных стилей. Вёрстка layout-обёрток выносится в слойlayouts/.- Стили в файлах роутинга не используются — стилизация только внутри вызываемых компонентов.
Реализация
- Каждый
page.tsxэкспортируетmetadataсtitle— он подставляется в шаблон корневого layout (%s | App). - Корневой
layout.tsxзадаётmetadataсtitle.template,description,metadataBaseи OpenGraph-настройками.
Примеры
src/app/profile/[id]/page.tsx
import type { Metadata } from 'next'
import { ProfileScreen } from '@/screens/profile'
export const metadata: Metadata = {
title: 'Профиль',
description: 'Страница профиля пользователя',
}
type ProfilePageProps = {
params: Promise<{ id: string }>
}
export default async function ProfilePage({ params }: ProfilePageProps) {
const { id } = await params
return <ProfileScreen id={id} />
}
src/app/error.tsx
'use client'
import { ErrorScreen } from '@/screens/error'
type ErrorPageProps = {
error: Error & { digest?: string }
reset: () => void
}
const ErrorPage = ({ error, reset }: ErrorPageProps) => {
return <ErrorScreen error={error} reset={reset} />
}
export default ErrorPage