Files
svg-sprites/preview/ai/applied/page-level.md
S.Gromov e77e7dfcf1 refactor: заменить shiki на самописный highlighter и обновить архитектуру
- Удалён shiki (9.5→0 МБ), создан regex-токенизатор для html/css/xml
- CLI переведён с аргументов на конфиг-файл svg-sprites.config.ts
- Превью переработано: React-приложение вместо инлайн HTML
- Добавлен футер с названием пакета и ссылкой на репозиторий
- Исправлена загрузка dev-data.js для Vite 8
- Футер прижат к низу, содержимое центрировано
2026-04-22 16:54:35 +03:00

2.7 KiB
Raw Blame History

title, scope, keywords, when
title scope keywords when
Файлы роутинга applied
page.tsx
layout.tsx
error.tsx
not-found.tsx
loading.tsx
App Router
metadata
Работа с файлами роутинга 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