Skip to content

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 /kontakt

Slug 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 w translatedPaths($article, '/:blog/%s')), rozwijany przez LocaleService::translatePath().
  • Motyw: routePath('blog', slug) z composable useLocale(), oparte na propie routeSegments. Wynik przekazuj do komponentu AppLink, 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 ​

  1. Dopisz kod języka do locales w config/translatable.php i etykietę do locales.names w Modules/Core/Config/site.php.
  2. Włącz język: php artisan mb:set-locales albo ręcznie w SITE_LOCALES w .env.
  3. Dodaj resources/js/site/lang/<kod>.ts i uwzględnij go w resources/js/site/lib/i18n.ts.
  4. W panelu przetłumacz i aktywuj strony (tytuł i slug), artykuły, menu z pozycjami oraz teksty statyczne.
  5. Przebuduj motyw (npm run build:ssr). Po ręcznej zmianie .env przy cache'owanej konfiguracji lub trasach uruchom php artisan config:clear && php artisan route:clear.
  6. Sprawdź / i /<kod>, przełącznik języka, hreflang w źródle strony i php 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ń.

Made by Moonbite