Next.js 15.1 приносит основные обновления, новые API и улучшения для разработчиков. Ключевые изменения включают:
- React 19 (стабильная версия): Официальная поддержка React 19 как для Pages Router, так и для App Router.
- Улучшенная отладка ошибок: Улучшенный опыт разработки и более качественные source maps для браузера и терминала.
after
(стабильная версия): Новый API для выполнения кода после завершения потоковой передачи ответа.forbidden
/unauthorized
(экспериментальные): Новые API для более детализированной обработки ошибок аутентификации.
Обновите сегодня или начните с:
# Используйте автоматизированный CLI для обновления
npx @next/codemod@canary upgrade latest
# ...или обновите вручную
npm install next@latest react@latest react-dom@latest
# ...или создайте новый проект
npx create-next-app@latest
React 19 (стабильная версия)
Next.js 15.1 теперь полностью поддерживает React 19:
- Для Pages Router: теперь можно использовать стабильную версию React 19 без необходимости Release Candidate или Canary-релизов, наряду с продолжающейся поддержкой React 18.
- Для App Router: мы продолжим предоставлять встроенные Canary-релизы React. Они включают все стабильные изменения React 19, а также новые функции, проверяемые в фреймворках перед новым релизом React.
С момента выхода Next.js 15, значительным дополнением к React 19 стало "sibling pre-warming".
Для полного обзора обновлений React 19 обратитесь к официальному блогу React 19.
Улучшенная отладка ошибок
Мы улучшили отладку ошибок в Next.js, чтобы вы могли быстрее находить их источник, независимо от того, где они появляются: в терминале, браузере или подключенных отладчиках. Эти улучшения применяются как к Webpack, так и к Turbopack (теперь стабильной версии с Next.js 15).
Улучшения source maps
Теперь ошибки легче отслеживать благодаря улучшенному использованию source maps. Мы реализовали свойство ignoreList
source maps, которое позволяет Next.js скрывать стек-фреймы внешних зависимостей, фокусируясь на коде вашего приложения.
Для более точного сопоставления source maps с именами методов мы рекомендуем использовать Turbopack (теперь стабильную версию), который лучше обрабатывает и обнаруживает source maps по сравнению с Webpack.
Для авторов библиотек: Рекомендуем заполнять свойство
ignoreList
в source maps при публикации библиотек, особенно если они настроены как внешние (например, в конфигурацииserverExternalPackages
).
Свернутые стек-фреймы
Мы улучшили логику сворачивания стек-фреймов, чтобы выделить наиболее релевантные части вашего кода.
- В браузере и оверлее ошибок: Стек-фреймы из сторонних зависимостей по умолчанию скрыты, фокусируясь на коде вашего приложения. Вы можете показать скрытые фреймы, нажав "Show ignored frames" в devtools или оверлее.
- В терминале: Фреймы сторонних зависимостей также свернуты по умолчанию, а форматирование ошибок теперь соответствует выводу в браузере для единообразного опыта отладки. Ошибки воспроизводятся в браузере, чтобы вы не пропустили важную информацию во время разработки, если вам нужен полный стек вызовов.
Улучшенное профилирование
Игнорируемые стек-фреймы также распознаются встроенными профилировщиками браузеров. Это упрощает профилирование вашего приложения, позволяя точно определить медленные функции в вашем коде без шума от внешних библиотек.
Улучшения для Edge Runtime
При использовании Edge Runtime ошибки теперь отображаются единообразно во всех средах разработки, обеспечивая бесперебойную отладку. Ранее залогированные ошибки включали только сообщение без стека.
До и после
Терминал До:
⨯ app/page.tsx (6:11) @ eval
⨯ Error: boom
at eval (./app/page.tsx:12:15)
at Page (./app/page.tsx:11:74)
at AsyncLocalStorage.run (node:async_hooks:346:14)
at stringify (<anonymous>)
at AsyncLocalStorage.run (node:async_hooks:346:14)
at AsyncResource.runInAsyncScope (node:async_hooks:206:9)
digest: "380744807"
4 | export default function Page() {
5 | const throwError = myCallback(() => {
> 6 | throw new Error('boom')
| ^
7 | }, [])
8 |
9 | throwError()
GET / 500 in 2354ms
Терминал После:
⨯ Error: boom
at eval (app/page.tsx:6:10)
at Page (app/page.tsx:5:32)
4 | export default function Page() {
5 | const throwError = myCallback(() => {
> 6 | throw new Error('boom')
| ^
7 | }, [])
8 |
9 | throwError() {
digest: '225828171'
}
Оверлей ошибок До

Оверлей ошибок После

Эти улучшения делают ошибки более понятными и интуитивными, позволяя вам сосредоточиться на разработке приложения, а не на отладке.
Мы также рады объявить о введении переработанного интерфейса для оверлея ошибок, который появится в будущих релизах.
after
(стабильная версия)
API after()
теперь стабильно после его введения в первом RC Next.js 15.
after()
предоставляет способ выполнения таких задач, как логирование, аналитика и синхронизация системы после завершения потоковой передачи ответа пользователю, не блокируя основной ответ.
Ключевые изменения
С момента его введения мы стабилизировали after()
и учли отзывы, включая:
- Улучшенную поддержку для самостоятельно размещенных серверов Next.js.
- Исправления ошибок для сценариев, где
after()
взаимодействовал с другими функциями Next.js. - Улучшенную расширяемость, позволяя другим платформам внедрять свои примитивы
waitUntil()
для работыafter()
. - Поддержку API времени выполнения, таких как
cookies()
иheaders()
в Server Actions и Route Handlers.
import { after } from 'next/server';
import { log } from '@/app/utils';
export default function Layout({ children }) {
// Вторичная задача
after(() => {
log();
});
// Основная задача
return <>{children}</>;
}
Подробнее об API after
и его использовании читайте в документации.
forbidden
и unauthorized
(экспериментальные)
Next.js 15.1 включает два экспериментальных API, forbidden()
и unauthorized()
, основанных на отзывах сообщества.
Нам важны ваши отзывы — попробуйте их в своих средах разработки и поделитесь мнением в этой ветке обсуждения.
Обзор
Если вы знакомы с App Router, вы, вероятно, использовали notFound()
для вызова поведения 404 вместе с настраиваемым файлом not-found.tsx
. В версии 15.1 мы расширяем этот подход для ошибок авторизации:
• forbidden()
вызывает ошибку 403 с настраиваемым интерфейсом через forbidden.tsx
.
• unauthorized()
вызывает ошибку 401 с настраиваемым интерфейсом через unauthorized.tsx
.
Важно знать: Как и с ошибками
notFound()
, статусный код будет200
, если ошибка вызвана после отправки начальных заголовков ответа. Подробнее.
Включение функции
Поскольку эта функция все еще экспериментальная, вам нужно включить ее в файле next.config.ts
:
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
experimental: {
authInterrupts: true,
},
};
export default nextConfig;
Примечание: Поддержка
next.config.ts
была введена в Next.js 15. Подробнее.
Использование forbidden()
и unauthorized()
Вы можете использовать forbidden()
и unauthorized()
в Server Actions, Server Components, Client Components или Route Handlers. Вот пример:
import { verifySession } from '@/app/lib/dal';
import { forbidden } from 'next/navigation';
export default async function AdminPage() {
const session = await verifySession();
// Проверяем, есть ли у пользователя роль 'admin'
if (session.role !== 'admin') {
forbidden();
}
// Рендерим страницу администратора для авторизованных пользователей
return <h1>Admin Page</h1>;
}
Создание пользовательских страниц ошибок
Для настройки страниц ошибок создайте следующие файлы:
import Link from 'next/link';
export default function Forbidden() {
return (
<div>
<h2>Доступ запрещен</h2>
<p>У вас нет прав для доступа к этому ресурсу.</p>
<Link href="/">Вернуться на главную</Link>
</div>
);
}
import Link from 'next/link';
export default function Unauthorized() {
return (
<div>
<h2>Неавторизованный доступ</h2>
<p>Пожалуйста, войдите в систему для доступа к этой странице.</p>
<Link href="/login">Перейти к входу</Link>
</div>
);
}
Мы благодарим Clerk за предложение этой функции через PR и помощь в прототипировании API. Прежде чем стабилизировать эту функцию в 15.2, мы планируем добать больше возможностей и улучшений в API для поддержки более широкого спектра сценариев использования.
Читайте документацию по API unauthorized
и forbidden
для получения дополнительной информации.
Другие изменения
- [Функция] Использование ESLint 9 в
create-next-app
(PR) - [Функция] Увеличение максимального количества тегов кэша до 128 (PR)
- [Функция] Добавлена опция отключения экспериментального CssChunkingPlugin (PR)
- [Функция] Добавлена экспериментальная поддержка встраивания CSS (PR)
- [Улучшение] Устранено предупреждение Sass
legacy-js-api
(PR) - [Улучшение] Исправлена необработанная ошибка при использовании rewrites (PR)
- [Улучшение] Обеспечен выход родительского процесса при сбое webpack worker (PR)
- [Улучшение] Исправлено перехватывание маршрутов на catch-all route (PR)
- [Улучшение] Исправлена проблема с клонированием ответа при дедупликации запросов (PR)
- [Улучшение] Исправлены редиректы Server Action между несколькими корневыми макетами (PR)
- [Улучшение] Поддержка предоставления MDX-плагинов в виде строк для совместимости с Turbopack (PR)
Участники
Next.js — это результат совместной работы более 3000 разработчиков. Этот релиз стал возможен благодаря:
- Команде Next.js: Andrew, Hendrik, Janka, Jiachi, Jimmy, Jiwon, JJ, Josh, Jude, Sam, Sebastian, Sebbie, Wyatt, и Zack.
- Команде Turbopack: Alex, Benjamin, Donny, Maia, Niklas, Tim, Tobias, и Will.
- Команде Next.js Docs: Delba, Rich, Ismael, и Lee.
Огромная благодарность @sokra, @molebox, @delbaoliveira, @eps1lon, @wbinnssmith, @JamBalaya56562, @hyungjikim, @adrian-faustino, @mottox2, @lubieowoce, @bgw, @mknichel, @wyattjoh, @huozhi, @kdy1, @mischnic, @ijjk, @icyJoseph, @acdlite, @unstubbable, @gaojude, @devjiwonchoi, @cena-ko, @lforst, @devpla, @samcx, @styfle, @ztanner, @Marukome0743, @timneutkens, @JeremieDoctrine, @ductnn, @karlhorky, @reynaldichernando, @chogyejin, @y-yagi, @philparzer, @alfawal, @Rhynden, @arlyon, @MJez29, @Goodosky, @themattmayfield, @tobySolutions, @kevinmitch14, @leerob, @emmanuelgautier, @mrhrifat, @lid0a, @boar-is, @nisabmohd, @PapatMayuri, @ovogmap, @Reflex2468, @LioRael, @betterthanhajin, @HerringtonDarkholme, @bpb54321, @ahmoin, @Kikobeats, @abdelrahmanAbouelkheir, @lumirlumir, @yeeed711, @petter, и @suu3 за помощь!