Motyw
Wielojęzyczne adresy URL
Język domyślny nie ma członu w adresie, pozostałe mają prefiks z kodem języka:
text
/ /kontakt /blog/moj-wpis → pl (domyślny)
/en /en/contact /en/blog/my-post → en
/pl/kontakt → 301 na /kontaktSlug pochodzi z tłumaczenia modelu i jest unikalny w obrębie języka. Stałe człony tras (np. /blog) mogą mieć wersję per język — zob. Tłumaczone człony tras. Zmienne SITE_LOCALES i SITE_DEFAULT_LOCALE opisują Pierwsze kroki.
Backend
Route::localized() rejestruje grupę tras motywu raz na język. Język domyślny zachowuje gołe nazwy tras (route('page.show')), pozostałe dostają prefiks nazwy (route('en.page.show')). Middleware Modules\Core\Http\Middleware\SetLocale ustawia język aplikacji według prefiksu — o języku decyduje URL, nie parametr ?lang=.
Reguły budowania ścieżek trzyma Modules\Core\Services\LocaleService; muszą pozostać zgodne z helperami w resources/js/site/lib/locale.ts. Adres z prefiksem języka domyślnego (/pl/kontakt) jest przekierowywany 301 na adres bez prefiksu przez Route::redirectDefaultLocalePrefix().
Kontroler renderujący model tłumaczony rejestruje adresy alternatywne:
php
$this->shareAlternatePaths($this->translatedPaths($page));
$this->shareAlternatePaths($this->translatedPaths($article, '/:blog/%s'));Z nich powstają <link rel="alternate" hreflang> z x-default w site.blade.php oraz prop locales dla przełącznika języka. seo:sitemap generuje adresy dla każdego języka.
Treść bez aktywnego tłumaczenia (translation_active) nie istnieje pod adresem danego języka — nie ma podmiany na język domyślny (use_fallback w config/translatable.php jest wyłączony).
Tłumaczone człony tras
Stały człon adresu ma klucz (blog) i tłumaczenia w route_segments w Modules/Core/Config/site.php:
php
'route_segments' => [
'blog' => ['pl' => 'blog', 'en' => 'blog'],
],Z mapy korzystają wszystkie miejsca budujące adres:
- Trasa w
Route::localized():Route::get(Route::segment('blog').'/{slug}', ...)— makro zwraca człon dla języka, dla którego grupa jest właśnie rejestrowana. - Backend:
LocaleService::segment('blog', $locale), a w formatach ścieżek placeholder:blog(jak wtranslatedPaths($article, '/:blog/%s')), rozwijany przezLocaleService::translatePath(). - Motyw:
routePath('blog', slug)z composableuseLocale(), oparte na propierouteSegments. Wynik przekazuj do komponentuAppLink, który dokleja prefiks języka.
Po zmianie mapy przy cache'owanych trasach uruchom php artisan route:clear. Zmiana członu nie tworzy przekierowania ze starego adresu — dodaj je w module Redirect.
Dodanie języka
- Dopisz kod języka do
localeswconfig/translatable.phpi etykietę dolocales.nameswModules/Core/Config/site.php. - Włącz język:
php artisan mb:set-localesalbo ręcznie wSITE_LOCALESw.env. - Dodaj
resources/js/site/lang/<kod>.tsi uwzględnij go wresources/js/site/lib/i18n.ts. - W panelu przetłumacz i aktywuj strony (tytuł i slug), artykuły, menu z pozycjami oraz teksty statyczne.
- Przebuduj motyw (
npm run build:ssr). Po ręcznej zmianie.envprzy cache'owanej konfiguracji lub trasach uruchomphp artisan config:clear && php artisan route:clear. - Sprawdź
/i/<kod>, przełącznik języka, hreflang w źródle strony iphp artisan seo:sitemap.
Nowa strona motywu
Trasę rejestruj wewnątrz Route::localized() w miejscu markera // inertia-routes //, a w kontrolerze modelu tłumaczonego wywołaj shareAlternatePaths() z translatedPaths(). Prefiks w linkach, język aplikacji i hreflang wynikają wtedy z adresu.
Instancja vue-i18n powstaje osobno dla każdej aplikacji (createAppI18n w app.ts) z językiem wziętym z URL, bo pod SSR jeden proces Node obsługuje wiele żądań.