Ловушки обновления Next.js 16: параметры по умолчанию параллельных маршрутов и прокси-мидлвэры
Узнайте, почему в Next.js 16 для параллельных слотов маршрутов требуется файл default.js, как безопасно перенести код из middleware.ts в proxy.ts и что необходимо протестировать перед тем, как считать обновление завершённым.
Источники: Parallel Routes and proxy.ts in Next.js 16: The Routing Changes That Catch Teams Off Guard
Большая часть усилий при обновлении до Next.js 16 направлена на изменения в асинхронных объектах params и searchParams, поскольку они вызывают серьезные сбои во всех частях приложения. Два менее заметных изменения в механизме маршрутизации также требуют пристального внимания: теперь для параллельных слотов маршрутов необходим файл default.js, а функции перехвата запросов перемещаются из middleware.ts в новую конвенцию proxy.ts. Ни одно из этих изменений не нарушает работу страниц, которыми вы пользуетесь ежедневно, и именно поэтому они часто остаются незамеченными в процессе тестирования. В этом руководстве объясняются оба изменения, почему они проявляются поздно, а также приводится чек-лист для проверки перед выпуском обновления.
Для параллельных слотов маршрутов требуется файл default.js
В параллельных схемах для определения именованных слотов, которые отображаются рядом друг с другом, используются папки с префиксом @. Классическим примером являются панели управления: основная область контента рядом с постоянным потоком активностей или панелью уведомлений, причем каждая из них имеет собственное состояние навигации.
В Next.js 16 от каждого слота ожидается наличие файла default.js. Именно этот файл отображается Next.js для слота, когда в текущем URL нет более специфичного совпадения. В отсутствие такого файла навигация на соответствующую комбинацию возвращает ошибку 404 вместо плавного перехода, и согласно записям об обновлении Next.js 16 сборка может отказаться продолжаться, если у слота нет файла default, поэтому необходимо уточнить точное поведение для вашей версии. Панель управления с слотом для потока данных выглядит следующим образом:
app/
dashboard/
@feed/
page.tsx ← the "active" state for this slot
default.js ← required fallback when no more-specific match exists
layout.tsx
page.tsx
Заглушка редко требует сложных действий. Отображение значения null скрывает соответствующее поле, а компонент состояния пустоты позволяет сохранить видимость панели:
// app/dashboard/@feed/default.js
export default function Default() {
return null;
}
Почему отсутствующее значение по умолчанию проявляется поздно
Во время разработки вы в основном переходите между состояниями, которые создали и протестировали, и все они соответствуют чему-то в каждом поле. Проблема возникает, когда пользователь попадает в комбинацию, которую никто ранее не пробовал: глубокая ссылка, обновление страницы по вложенному URL или маршрут, существующий для основного контента, но не для ленты новостей. Полная загрузка страницы не может повторно использовать предыдущее состояние поля, поэтому Next.js нуждается в файле default.js, чтобы знать, что отображать. На практике это означает, что сообщение об ошибке 404 часто поступает от растерянного клиента в продакшене, а не обнаруживается во время разработки. Добавление файла для каждого поля, даже если кажется, что он никогда не будет использован, является недорогой мерой предосторожности.
От middleware.ts к proxy.ts
Второе изменение касается перехвата запросов на уровне запроса. Next.js 16 вводит proxy.ts как стандартную практику для логики, ранее находившейся в middleware.ts, при этом старое название файла постепенно устраняется. На момент написания этого текста миграция подразумевает переименование файла и экспортируемой им функции; прокси предназначен для работы в среде выполнения Node.js. Для получения деталей и официального кода-модификатора, выполняющего техническую часть работы, ознакомьтесь с актуальной документацией.
Если ваш мидлвэр прост, процесс перехода займет немного времени. Если же он выполняет важные функции, такие как проверка авторизации, определение тенантов по поддоменам, перенаправления или изменение заголовков, рассматривайте это как изменение кода, требующее проверки, а не просто переименование файла.
Проверяйте функции по отдельности, а не просто переименовывайте их
Автоматическое замещение из файла middleware.ts в файл proxy.ts предполагает, что вся логика будет работать одинаково согласно новым правилам. Вместо этого необходимо тщательно изучить, что на самом деле делает каждый файл, и отдельно проверить каждую из его функций:
- какие запросы покрывает конфигурация сопоставления, а также были ли добавлены или удалены какие-либо пути
- как принимаются решения по аутентификации и что происходит, когда сессия отсутствует или истекла
- как идентификаторы арендаторов извлекаются из имен хостов или заголовков и передаются дальше
- какие перенаправления и перезаписи выполняются и в каком порядке
- какие заголовки считываются, добавляются или удаляются
Именно на этом уровне незначительная разница в поведении превращается из косметической проблемы в угрозу безопасности. Пропущенная запись-соответствие может оставить маршрут без аутентификации; изменение заголовка может нарушить изоляцию тенантов. Поэтому этот аспект требует тщательного анализа и тестирования «от начала до конца», а не лишь визуальной проверки.
Два независимых изменения с одинаковым паттерном сбоев
Параметры по умолчанию маршрутов и миграция прокси технически не связаны друг с другом. Команды часто обнаруживают их в ходе одной и той же процедуры обновления, поскольку у них схожий паттерн: в разработке оба решения в основном работают, но ломаются в определенных сценариях работы в продакшене, которые трудно воспроизвести.
Такой паттерн стоит назвать. Изменения, нарушающие работу при каждой загрузке страницы, обнаруживаются в течение нескольких минут. Рискованные изменения проявляются только при необычных путях навигации или определенных форматах запросов, поэтому обычный ручной переход никогда их не активирует. Ваш план тестирования должен целенаправленно охватывать именно такие пути.
Чек-лист для аудита перед обновлением
Прежде чем считать обновление до Next.js 16 завершенным, проверьте следующее:
- У каждого параллельного маршрута имеется файл
default.js. Поищите в каталогеapp/папки, начинающиеся с символа@, и проверьте каждую из них. - Логика мидлвэра была проверена с учетом стандартов файла
proxy.ts, причем рассматривалась одна функция за раз; файлы не были переименованы, и предполагалось, что они идентичны.
Почему панели управления с поддержкой нескольких тенантов несут наибольший риск
Панели управления типа SaaS часто объединяют обе эти функции: параллельные маршруты для различных элементов интерфейса и промежуточное программное обеспечение, которое сопоставляет поддомен с тенантом перед отображением любой страницы. Это приводит к тому, что процесс определения тенанта находится непосредственно в коде, наиболее подверженном изменениям при использовании прокси.
Ошибка здесь редко приводит к серьезным последствиям. Вместо страницы с ошибкой появляются сообщения о том, что один арендатор кратковременно увидел данные другого арендатора, что является примерно настолько серьезным инцидентом, насколько это возможно в SaaS-продукте. Многоуровневая защита помогает: даже когда прокси определяет арендатора, доступ к данным в компонентах сервера и обработчиках маршрутов должен снова проверять принадлежность арендатора, вместо того чтобы полагаться на информацию из заголовков, переданных сверху. Для кэширования на основе тегов требуется такая же осторожность, поскольку ключи кэша должны включать информацию об арендаторе; статья о использовании кэша и повторной верификации на основе тегов в Next.js 16 рассматривает этот аспект.
Частые вопросы
Приведет ли пропуск файла default.js к бесшумной ошибке?
Не совсем. В версиях, где действует это правило, появляется ошибка 404 или ошибка сборки, но только для тех путей навигации, которые ведут к отсутствующему резервному варианту. Поскольку ошибка возникает далеко от того места, которое её вызвало, её легко принять за общую ошибку маршрутизации, если вы не знакомы с этим изменением.
Можно ли пока продолжать использовать middleware.ts?
Проверьте документацию Next.js для вашей конкретной минорной версии, поскольку поддержка старой конвенции постоянно развивается. Учитывая то, насколько часто в этом файле находится логика аутентификации, откладывание миграции на неопределённый срок опаснее, чем отсрочка большинства других задач по обновлению, а выполнение её заранее даёт время для тщательного анализа.
Как быстро найти слоты без default.js?
Поищите папки внутри app/, названия которых начинаются с @, и выделите те, в которых отсутствует файл default.js (или default.tsx). Одна процедура поиска файлов в вашем редакторе или короткий командлет в терминале позволят найти все такие папки.
Заключение
Самые вероятные проблемы при обновлении до Next.js 16 связаны не с теми изменениями, которые нарушают стандартный работоспособный сценарий. Параллельные маршруты без значения по умолчанию, а также проексы с спешными изменениями имен прокси успешно проходят обычные тесты, но срываются при редких сценариях использования, что иногда приводит к проблемам с безопасностью. Добавьте значение по умолчанию к каждому маршруту, тщательно проверьте логику перехвата запросов по отдельности и уделите достаточно времени на реальные тестирования маршрутов, к которым обычный анализ никогда не относится.