Специальные файлы и страница 404
Кроме page.tsx и layout.tsx Next.js распознаёт в папках маршрутов ещё несколько файлов с особыми именами. Каждый отвечает за своё состояние страницы: загрузку, ошибку, отсутствие данных. Здесь — обзор и страница 404, остальные файлы разобраны в своих уроках.
Специальные файлы
| Файл | Когда показывается |
|---|---|
page.tsx | Содержимое страницы |
layout.tsx | Общая обёртка для страниц папки |
loading.tsx | Пока страница загружает данные |
error.tsx | Если при отрисовке произошла ошибка |
not-found.tsx | Если страница или данные не найдены |
route.ts | Вместо страницы — обработчик API |
Своя страница 404
Создайте app/not-found.tsx:
// app/not-found.tsx
import Link from 'next/link';
export default function NotFound() {
return (
<main>
<h1>Страница не найдена</h1>
<Link href="/">На главную</Link>
</main>
);
}Откройте любой несуществующий адрес, например /abc, — появится этот текст вместе с шапкой из корневого макета. Сервер ответит со статусом 404.
Функция notFound()
В уроке о динамических маршрутах страница статьи сама рисовала «Статья не найдена», а сервер при этом отвечал статусом 200. Правильнее вызвать функцию notFound():
// app/posts/[slug]/page.tsx
import { notFound } from 'next/navigation';
import { getPost } from '@/lib/posts';
export default async function PostPage({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const post = await getPost(slug);
if (!post) {
notFound();
}
return <h1>{post.title}</h1>;
}Адрес /posts/abc теперь показывает страницу 404 со статусом 404. Код после notFound() не выполняется, поэтому TypeScript знает, что ниже post уже не undefined.
Отдельная 404 для раздела
Файл not-found.tsx можно положить и в папку раздела. Тогда notFound(), вызванная внутри статьи, покажет более точный текст:
// app/posts/[slug]/not-found.tsx
export default function PostNotFound() {
return <p>Такой статьи нет. Возможно, её удалили.</p>;
}Next.js ищет ближайший not-found.tsx, поднимаясь от папки страницы к корню app/.
Частая ошибка
Вызывать notFound() внутри try...catch. Функция работает, выбрасывая специальное исключение, и catch его перехватит — страница 404 не появится. Вызывайте notFound() вне блока try или выбрасывайте ошибку дальше.