Підводні камені оновлення до 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, процес збірки може відмовитися продовжуватися, якщо слот не має значення за замовчуванням, тому необхідно перевірити точну поведінку для вашої версії. Панель керування зі слотом для потоку подій виглядає так:
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 часто повідомляється розгубленим клієнтом у продакшені, а не виявляється під час розробки. Додавання файлу для кожного поля, навіть якщо ви думаєте, що його ніколи не використають, — це недороге страхування.
Друга зміна стосується перехоплення запитів на рівні клієнта. Next.js 16 вводить proxy.ts як стандарт для логіки, яка раніше знаходилася у middleware.ts, і стару назву файлу поступово скасовують. На момент написання цього тексту міграція полягає у зміні назви файлу та експортованої функції, причому проксі призначений для роботи в середовищі Node.js; деталі та офіційний код для виконання цих змін можна знайти у поточній документації.
Якщо ваш middleware є простим, процес міграції швидкий. Якщо він виконує складні функції, такі як перевірка автентифікації, ідентифікація користувачів за піддоменами, перенаправлення чи зміна заголовків, слід розглядати це як зміну коду, яка потребує перевірки, а не просто зміну назви файлу.
Перевіряйте функції по одній, а не просто змінюйте назви
Автоматичне замінення з 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). Одноразовий пошук у вашому редакторі чи короткий командний запит shell допоможуть знайти всі такі випадки.
Підсумок
Зміни в Next.js 16, які найімовірніше спричинять проблеми, — це не ті, що порушують звичайний робочий процес. Паралельні слоти маршрутів без значення за замовчуванням та поспішно перейменовані проксі-файли проходять поверхневу перевірку, але зазнають невдач у крайніх ситуаціях, іноді призводячи до проблем з безпекою. Додайте значення за замовчуванням до кожного слота, ретельно перегляньте логіку перехоплення за кожною з них та виділіть достатньо часу на справжню перевірку маршрутів, які не піддаються звичайному тестуванню.