Suteikite kiekvienai kalbai atskirą URL, o tada susiekite šiuos URL abipusėmis hreflang žymomis. Išskleidžiamasis sąrašas, keičiantis eilutes React būsenoje, išverčia sąsają jau jūsų svetainėje esančiam žmogui, tačiau nesukuria nieko, ką galėtų indeksuoti paieškos sistema, todėl vokiškos ir ispaniškos versijos lieka nematomos. globalize.now yra dirbtiniu intelektu paremta lokalizacijos infrastruktūra, kuri ištraukia kode įrašytas eilutes į į saugyklą įtrauktus Lingui PO katalogus ir sinchronizuoja juos po kiekvieno Git push — būtent todėl atskirų lokalių maršrutų priežiūra tampa praktiška, o ne vienkartiniu varginančiu darbu.
Tai žingsnis, kurį dauguma Lovable kūrėjų praleidžia. Programa išversta, perjungiklis naršyklėje veikia, tačiau lankytojų taip ir neatsiranda.
Kodėl „Google“ neindeksuoja kitų mano Lovable programos kalbų?
Nes beveik neabejotinai šios kalbos neturi atskirų adresų.
Numatytasis šablonas, kurį sukuria DI kūrimo įrankis, yra useState lokalės reikšmė ir ją nustatantis išskleidžiamasis sąrašas. Kiekviena kalba atvaizduojama tuo pačiu URL. Tikrintuvas, užklausęs šį URL, gauna vieną atsakymą viena kalba ir indeksuoja vieną puslapį. Nėra ko atrasti ir nėra signalo, nurodančio, kad egzistuoja kitų kalbų versijos.
Sprendimas yra struktūrinis, o ne kosmetinis. Pačios „Google“ rekomendacijos dėl lokalizuotų versijų aiškiai nurodo, kad alternatyvūs kalbų puslapiai identifikuojami pagal URL, o juos susiejančios anotacijos turi būti grąžinamos kiekviename rinkinio puslapyje. Jei /de/pricing neegzistuoja kaip pasiekiamas adresas, jokie žymėjimai jo nepadarys matomo.
Ką turi daryti tikras kalbų perjungiklis?
Tris dalykus tokia tvarka: pakeisti URL, palikti naudotoją tame pačiame puslapyje ir įsiminti pasirinkimą.
URL pakeitimas yra svarbiausia dalis paieškai. Naudotojo palikimas tame pačiame puslapyje svarbus naudotojui, ir būtent čia dauguma realizacijų sugenda: perjungus iš /en/pricing turi būti atveriamas /de/pricing, o ne /de/. Pasirinkimo įsiminimas yra patogumo funkcija ir niekada neturėtų pakeisti URL aiškiai nurodytos lokalės.
Verta įvardyti vieną netinkamą praktiką: automatinį peradresavimą pagal naršyklės kalbą. Jei tikrintuvas iš Jungtinių Valstijų užklausia /de/pricing ir yra nukreipiamas į /en/pricing, vokiškas puslapis faktiškai neegzistuoja. Pasiūlykite perjungimą, bet neverskite jo naudoti.
Kaip pridėti lokalėms skirtą maršrutizavimą prie Lovable TanStack Start programos?
Maršrutų medžio viršuje pridėkite lokalės segmentą ir iš jo aktyvuokite katalogą.
2026 m. gegužę Lovable naujus projektus perkėlė į serverio pusėje atvaizduojamą TanStack Start, todėl lokalės prefiksą turintis maršrutas pirmuoju atsakymu grąžina visiškai išverstą HTML. Būtent tokio atsakymo reikia tikrintuvui.
Sukurkite dinaminį segmentą, apgaubiantį likusius maršrutus:
src/routes/
$locale/
route.tsx
index.tsx
pricing.tsx
Tada aktyvuokite tos lokalės Lingui katalogą prieš atvaizduojant antrinius maršrutus:
// src/routes/$locale/route.tsx
import { createFileRoute, Outlet, notFound } from "@tanstack/react-router";
import { i18n } from "@lingui/core";
import { I18nProvider } from "@lingui/react";
const LOCALES = ["en", "de", "es", "fr"] as const;
export const Route = createFileRoute("/$locale")({
loader: async ({ params }) => {
if (!LOCALES.includes(params.locale as (typeof LOCALES)[number])) {
throw notFound();
}
const { messages } = await import(
`../../locales/${params.locale}/messages.po`
);
i18n.loadAndActivate({ locale: params.locale, messages });
return { locale: params.locale };
},
component: LocaleLayout,
});
function LocaleLayout() {
return (
<I18nProvider i18n={i18n}>
<Outlet />
</I18nProvider>
);
}
Čia svarbios dvi detalės. Nežinomų lokalių atmetimas naudojant notFound() neleidžia /xx/pricing grąžinti „soft 200“ atsako kiekvienam tikrintuvo išbandytam atsitiktiniam keliui. Įkėlus katalogą maršruto įkėlimo funkcijoje, aktyvavimas įvyksta serveryje, prieš serializuojant HTML.
Jei naudojate senesnį steką, ta pati URL struktūra išlieka, tačiau skiriasi atvaizdavimo kelias. Lovable Vite i18n vadove aprašytas šis atvejis, o TanStack Start sąrankos vadove išsamiau paaiškinta SSR pusė.
Kaip sukurti kalbų perjungiklio komponentą?
Pereikite į tą patį maršrutą su kitu lokalės parametru ir kiekvieną parinktį atvaizduokite kaip tikrą nuorodą.
// src/components/LanguageSwitcher.tsx
import { Link, useLocation, useParams } from "@tanstack/react-router";
const LOCALES = {
en: "English",
de: "Deutsch",
es: "Español",
fr: "Français",
} as const;
export function LanguageSwitcher() {
const { locale } = useParams({ from: "/$locale" });
const { pathname } = useLocation();
const rest = pathname.replace(`/${locale}`, "") || "/";
return (
<nav aria-label="Language">
<ul>
{Object.entries(LOCALES).map(([code, label]) => (
<li key={code}>
<Link
to={`/${code}${rest}`}
hrefLang={code}
aria-current={code === locale ? "true" : undefined}
>
{label}
</Link>
</li>
))}
</ul>
</nav>
);
}
Parinktis atvaizduokite kaip nuorodas, o ne mygtukus, prijungtus prie maršrutizatoriaus iškvietimo. Nuorodas gali tikrinti paieškos sistemos, todėl jos suteikia paieškai antrą būdą atrasti lokalėms skirtus maršrutus, papildant svetainės schemą. Kiekvieną parinktį pavadinkite jos kalba, o ne vėliava: vėliavos žymi šalis, o ispanų kalba nėra šalis.
Kaip tinkamai generuoti hreflang žymas?
Kiekviename rinkinio puslapyje sugeneruokite po vieną anotaciją kiekvienai lokalei, įskaitant nuorodą į patį puslapį, taip pat x-default.
„Google“ tikrina, ar alternatyvūs URL pateikia nuorodas atgal, ir ignoruoja anotacijas, kurios nėra abipusės arba nukreipia nuo paties puslapio kanoninio URL. Todėl programinis jų generavimas yra vienintelis racionalus būdas: keturios kalbos dvidešimtyje puslapių sudaro 320 anotacijų, kurias rankiniu būdu išlaikyti nuoseklias būtų nepraktiška.
TanStack Start aplinkoje sukurkite jas maršruto head:
// src/routes/$locale/route.tsx (excerpt)
const SITE = "https://example.com";
const LOCALES = ["en", "de", "es", "fr"] as const;
export const Route = createFileRoute("/$locale")({
head: ({ params, location }) => {
const rest = location.pathname.replace(`/${params.locale}`, "") || "/";
return {
links: [
{ rel: "canonical", href: `${SITE}/${params.locale}${rest}` },
...LOCALES.map((code) => ({
rel: "alternate",
hrefLang: code,
href: `${SITE}/${code}${rest}`,
})),
{ rel: "alternate", hrefLang: "x-default", href: `${SITE}/en${rest}` },
],
};
},
});
Kadangi anotacijos gaunamos iš to paties LOCALES masyvo, kurį naudoja maršrutizatorius, pridėjus kalbą vienu metu atnaujinami maršrutai, perjungiklis ir hreflang rinkinys. Būtent šią savybę reikia išsaugoti: vienas sąrašas, trys naudotojai.
Įtraukite tuos pačius URL į svetainės schemą su xhtml:link alternatyvomis ir įsitikinkite, kad jūsų <html lang> atributas sutampa su aktyvia lokale. lang atributas hreflang neveikia, tačiau turi įtakos ekrano skaitytuvams ir naršyklės siūlomam vertimui.
Kodėl vykdymo metu veikiantis vertimo valdiklis negali to padaryti?
Nes valdiklis verčia tik tada, kai puslapis jau pateiktas anglų kalba.
Vykdymo metu veikiantis valdiklis pakeičia tekstą naršyklėje, kai įkeliamas jo scenarijus. Pirmasis tikrintuvo gaunamas atsakymas yra angliškas DOM, o išversta versija atsiranda tik paleidus kliento pusės JavaScript. Kai kurie valdikliai siūlo subdomenų arba poaplankių režimus su sugeneruotu hreflang, tačiau tokiu atveju URL struktūra ir anotacijos priklauso tiekėjo infrastruktūrai, o ne jūsų saugyklai.
Ši priklausomybė turi kainą, kuri jau nebėra hipotetinė. Lovalingo, tarp Lovable kūrėjų populiarus vertimo valdiklis, bus uždarytas 2026 m. rugpjūčio 31 d., o jų pačių rekomendacijose naudotojams siūloma pereiti prie projekto valdomo internacionalizavimo. Kai valdiklis išnyksta, kartu išnyksta ir jo sugeneruoti kalbų URL, o svetainė grįžta į anglų kalbą. Į saugyklą įtraukti katalogai ir jūsų kode apibrėžti maršrutai tokio jungiklio neturi. Praktinį šios migracijos aprašą pateikėme Lovalingo alternatyvų palyginime.
O kaip dėl klasikinio Vite SPA steko?
URL struktūra tokia pati, tačiau atvaizdavimas skiriasi.
Lovable projektai, sukurti prieš perėjimą prie TanStack Start, yra Vite ir React vieno puslapio programos, pateikiamos kaip statiniai failai ir atvaizduojamos naršyklėje. Vis tiek galite naudoti /:locale maršrutizavimą, generuoti hreflang ir saugoti katalogus saugykloje. Tačiau nebeturite garantijos, kad pirmasis tikrintuvo gautas baitas turės išverstą turinį.
Jei SEO yra pagrindinė priežastis, dėl kurios apskritai lokalizuojate programą, pridėkite lokalės maršrutų išankstinį atvaizdavimą, kad kiekvienas jų pateiktų tikrą HTML, arba planuokite pereiti prie serverio pusėje atvaizduojamo steko. Nespręskite problemos pridėdami vykdymo metu veikiantį valdiklį prie kliento pusėje atvaizduojamos programos — taip sukraunate du kliento pusės atvaizdavimo etapus ir pabloginate pirmąjį prasmingą atvaizdavimą kiekviena kalba.
Kaip neleisti keturioms lokalėms išsiskirti?
Automatizuokite ištraukimą ir laikykite katalogus išeities kodo dalimi.
Priežastis, dėl kurios atsisakoma lokalėms skirto maršrutizavimo, yra ne pats maršrutizavimas. Problema ta, kad kiekviena nauja funkcija prideda angliškų eilučių, kurių niekas neištraukia, todėl /de/ pamažu prisipildo angliškų fragmentų ir ima atrodyti prasčiau nei visiškai neturėti vokiečių kalbos. globalize.now tvarko šį sluoksnį: pridėkite lovable-i18n įgūdį savo Lovable darbo srityje ir paprašykite Lovable nustatyti i18n arba įdiekite įgūdžius lokaliai:
npx skills add globalize-now/globalize-skills
Pridėkite --all, kad jis būtų įdiegtas kiekvienam agentui. Naujos eilutės bus ištraukiamos, sugeneruojami raktai, išverčiami katalogai, o atnaujinti PO failai po kiekvieno Git push įrašomi atgal į saugyklą.
Kaina — 20 € per mėnesį vienai darbo sričiai, įskaitant 20 € vertimo kredito per mėnesį (apie 200 000 žodžių), o vėliau taikomas pagal žetonus skaičiuojamas naudojimas tuo pačiu tarifu už simbolį. Nėra mokesčių už naudotojus ar kalbas, todėl penktos lokalės pridėjimas pakeičia maršrutizavimo konfigūraciją, bet ne sąskaitą. Užsiregistravus suteikiama 5 € vertimo kredito ir nereikia kortelės. Daugiau informacijos rasite kūrėjams ir žmonėms, leidžiantiems DI sukurtas programas.
Maršrutizavimas ir hreflang yra vienos popietės darbas. Išlaikyti keturis katalogus užpildytus programai keičiantis — tai dalis, kuri niekada nesibaigia, ir būtent ją automatizuoja globalize.now.
globalize.now paverčia užkoduotą programos tekstą į vertimui paruoštus lokalės failus ir juos atnaujina, kai jūs diegiate naujus pakeitimus.
Išbandyti globalize.now nemokamai