Коли я інтегрувала власний localization package у ICanUp, основні localized routes одразу працювали без кешу.
Українська версія відкривалась без locale prefix, англійська через /en, перемикання мови працювало, а application code продовжував використовувати звичайні logical route names.
Але для мене інтеграція не була завершеною, поки той самий контракт не пережив реальний Laravel route:cache.

До інтеграції в мене вже був чіткий URL contract
Перед перевіркою cache я зафіксувала, що саме має залишитися незмінним.
У ICanUp українська є default locale, тому її public URLs не мають префікса. Англійська використовує /en.
Сценарій | Очікувана поведінка |
|---|---|
Default locale |
|
English |
|
Prefixed default locale |
|
Unknown explicit locale | Не повинна мовчки відкривати default locale |
Це важливо, тому що cache compatibility для мене означає не лише відсутність exception.
Після кешування URL contract повинен залишитися тим самим.
Спочатку я перевірила routes без cache
php artisan route:clear php artisan route:list \ --path=postsМені потрібен був baseline, з яким можна порівняти поведінку після кешування.
Я дивилась не тільки на URI, а й на route names, middleware та localized variants.
Потім створила справжній Laravel route cache
php artisan route:cacheУспішне завершення цієї команди є тільки першою перевіркою.
Воно означає, що Laravel зміг серіалізувати route collection. Воно ще не доводить, що після нового application boot коректно працюють URL generation, locale switching та інші runtime dependencies localization layer.
Чому я перевіряю application після нового boot
Route cache відновлює cached route collection, але application services під час наступного запуску створюються заново.
Тому інтеграція не повинна випадково залежати від runtime state, який існував лише під час початкової реєстрації routes.
Саме внутрішню причину такого багу я вже описувала окремо у статті про те, як route cache зламав URL generation у моєму localization package.
У цій статті мене цікавить наступний рівень: чи правильно поводиться продукт, який цей package використовує.
Logical route names повинні залишатися стабільними
Application code не повинен знати внутрішні назви localized route variants.
Контролери, Vue, SSR та інші частини застосунку повинні працювати зі стабільними logical route names так само до і після cache.
php artisan route:list \ --name=postsСам підхід зі stable logical names я детальніше розбирала у статті про logical route names та localized URLs у Laravel.
Я окремо перевірила default locale без prefix
Для української версії route cache не повинен раптом повернути locale prefix, якого немає в canonical routing contract.
curl -s \ -o /dev/null \ -w '%{http_code} %{url_effective}\n' \ https://icanup.com.ua/Те саме я перевіряю для реальних Post, Page та Category URLs.
Non-default locale повинна зберегти свій prefix
curl -s \ -o /dev/null \ -w '%{http_code} %{url_effective}\n' \ https://icanup.com.ua/enПісля cache /en має залишатися реальною English route, а не fallback на default locale.
Prefixed default locale має залишатися canonical redirect
В application contract default locale не повинна мати prefix.
Тому explicit /uk не стає другим indexable варіантом тієї самої сторінки. Localization layer переводить його на canonical unprefixed URL.
curl -s \ -o /dev/null \ -w '%{http_code} %{redirect_url}\n' \ https://icanup.com.ua/ukДля мене це також SEO regression check: route cache не повинен створювати новий duplicate URL лише через зміну способу завантаження route collection.
Unknown locale не повинна перетворюватися на default locale
Ще один важливий edge case - невідома або disabled explicit locale.
Я не хочу, щоб URL із невалідною мовою мовчки показував український контент. Така поведінка приховувала б помилки URL і створювала б неоднозначний routing.
Locale switch повинен зберігати поточний ресурс
Просто відкрити /en недостатньо.
Коли користувач змінює мову на конкретному Post або Page, застосунок повинен залишитися на тому самому ресурсі та сформувати URL через localization infrastructure.
- Route parameters не губляться.
- Query parameters не губляться.
- Shared slug залишається тим самим.
- Змінюється тільки locale-specific частина URL.
- Default locale повертається до unprefixed URL.
Route parameters і query string я перевіряю окремо
Localization package може правильно перемкнути просту homepage і водночас втратити parameters складнішого route.
Тому cache regression tests для мене обов'язково включають URL із route parameter та query string.
Current: /posts/example-slug?from=search Switch to EN: /en/posts/example-slug?from=search Switch back to UK: /posts/example-slug?from=searchNon-localized routes не повинні залежати від package
Під час інтеграції я не переносила під localization package все підряд.
Admin, API, webhook, authentication та інші service routes мають власний routing contract і не повинні змінюватися через кешування localized public routes.
- Admin routes залишаються non-localized.
- API routes не отримують locale prefix.
- Webhook routes не проходять через public localization logic.
- Authentication та service routes не змінюють свої names або URLs без окремої причини.
Після route:cache я запускаю повну application optimization
php artisan optimizeОкремий route:cache добре ізолює проблему routing.
Але production application зазвичай працює не в такому ізольованому режимі. Тому після targeted check я перевіряю повну optimization sequence, яку реально використовує deployment.
SSR і frontend URL generation теж входять у перевірку
У ICanUp routes використовуються не тільки PHP controllers.
Vue та Inertia SSR також генерують URLs, тому backend route cache може проявити проблему вже під час SSR rendering.
Цю межу я окремо розбирала у статті про Ziggy у Blade, Vue та Inertia SSR.
- SSR process стартує після deploy.
- Початковий HTML рендериться без route errors.
- Vue отримує той самий logical routing contract.
- Locale switch не залежить від client-only workaround.
- Localized links у SSR HTML відповідають application routes.
Що саме я перевіряю після cache
route:cacheзавершується без exception.- Default locale працює без prefix.
- EN routes працюють із
/en. - Prefixed default locale переходить на canonical unprefixed URL.
- Unknown explicit locale не відкриває default content мовчки.
- Logical route names працюють після нового application boot.
- Locale switch зберігає resource identity.
- Route parameters зберігаються.
- Query parameters зберігаються.
- Public canonical URLs не змінюються.
- Admin/API/service routes не отримують localization regressions.
- SSR і frontend URL generation продовжують працювати.
- Повний
artisan optimizeпроходить успішно.
Чого я більше не вважаю достатньою перевіркою
Раніше легко було б зупинитися на повідомленні Laravel про успішне кешування routes.
Після цього кейсу я так більше не роблю.
- Недостатньо тільки виконати
php artisan route:cache. - Недостатньо відкрити лише homepage.
- Недостатньо перевірити тільки default locale.
- Недостатньо перевірити тільки incoming requests.
- Недостатньо перевірити routes у тому самому application lifecycle, де вони реєструвалися.
Route cache compatibility для localization package - це не здатність Laravel створити cache file. Це здатність усього localized URL contract правильно працювати після нового application boot.
Що я залишила собі на майбутнє
- Спочатку зафіксувати routing baseline без cache.
- Перевіряти поведінку після реального cached boot.
- Тестувати incoming routing і URL generation окремо.
- Не забувати default locale redirect.
- Перевіряти unknown та disabled locale.
- Тестувати route parameters і query parameters.
- Не втягувати non-localized routes у localization infrastructure.
- Перевіряти SSR та frontend routing разом із backend.
- Після targeted route check запускати production-like optimization.
Висновок
Після інтеграції localization package в ICanUp команда route:cache стала для мене не останнім кроком, а початком перевірки.
Мені важливо, щоб після cached boot залишалися правильними ті самі URLs, route names, locale redirects, parameters, frontend links та SSR behavior.
Якщо localization architecture працює тільки до route cache, для production вона ще не готова.



