Andke igale keelele oma URL ja lisage neile URL-idele vastastikku viitavad hreflang-märgendid. Reacti olekus stringe vahetav rippmenüü tõlgib liidese inimese jaoks, kes on juba teie saidil, kuid ei loo otsingumootori jaoks midagi indekseeritavat, mistõttu jäävad teie saksa- ja hispaaniakeelsed versioonid nähtamatuks. globalize.now on tehisintellektil põhinev lokaliseerimistaristu, mis eraldab hardcoded stringid versioonihaldusesse lisatud Lingui PO-kataloogidesse ja hoiab need iga Git push’i järel sünkroonis. Nii on lokaalepõhiseid marsruute praktiline hooldada, mitte tegemist ühekordse käsitööga.

See on samm, mille enamik Lovable’i ehitajaid vahele jätab. Rakendus saab tõlgitud, keelevalija töötab brauseris, kuid liiklust ei saabu kunagi.


Miks Google minu Lovable’i rakenduse teisi keeli ei indekseeri?

Sest neil keeltel pole peaaegu kindlasti oma aadresse.

AI-ehitaja loodud vaikemuster on useState lokaali väärtus ja seda määrav rippmenüü. Kõik keeled renderdatakse samal URL-il. Seda URL-i päriv roomaja saab ühe vastuse ühes keeles ja indekseerib ühe lehe. Tal pole midagi avastada ega signaali, mis ütleks, et olemas on ka teised keeleversioonid.

Lahendus on struktuurne, mitte kosmeetiline. Google’i enda lokaliseeritud versioonide juhised ütlevad selgelt, et alternatiivsed keelelehed tuvastatakse URL-i järgi ning neid ühendavad märkused peavad tulema tagasi igalt sama komplekti lehelt. Kui /de/pricing ei eksisteeri päringu kaudu kättesaadava aadressina, ei too ükski märgend seda nähtavale.


Mida peab päris keelevalija tegema?

Kolm asja, selles järjekorras: muutma URL-i, jätma kasutaja samale lehele ja valiku meelde jätma.

URL-i muutmine on otsingu jaoks oluline osa. Kasutaja samale lehele jätmine on oluline kasutaja jaoks ja just siin enamik teostusi ebaõnnestub: /en/pricing-ilt vahetamine peaks viima aadressile /de/pricing, mitte aadressile /de/. Valiku meeldejätmine on mugavusfunktsioon ega tohiks kunagi tühistada URL-is sõnaselgelt määratud lokaali.

Üks halb muster väärib eraldi nimetamist: brauseri keele põhised automaatsed ümbersuunamised. Kui Ameerika Ühendriikides asuva roomaja päringule /de/pricing vastatakse ümbersuunamisega aadressile /en/pricing, siis saksa lehte sisuliselt ei eksisteeri. Pakkuge keelevahetust, ärge sundige seda.


Kuidas lisada Lovable’i TanStack Starti rakendusele lokaalipõhine marsruutimine?

Lisage marsruudipuu tippu lokaali segment ja aktiveerige selle põhjal kataloog.

Lovable viis uued projektid 2026. aasta mais üle TanStack Starti serveripoolsele renderdamisele, mistõttu lokaali prefiksiga marsruut tagastab juba esimese vastusega täielikult tõlgitud HTML-i. Just seda soovite roomajale saata.

Looge dünaamiline segment, mis ümbritseb ülejäänud marsruute:

src/routes/
  $locale/
    route.tsx
    index.tsx
    pricing.tsx

Seejärel aktiveerige selle lokaali Lingui kataloog enne alamkomponentide renderdamist:

// 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>
  );
}

Siin teevad tegeliku töö ära kaks detaili. Tundmatute lokaalide tagasilükkamine notFound() abil takistab /xx/pricing-il tagastamast iga roomaja proovitud suvalise rämpsraja kohta pehmet 200-vastust. Kataloogi laadimine marsruudi loader’is tähendab, et aktiveerimine toimub serveris enne HTML-i serialiseerimist.

Kui kasutate vanemat tehnoloogiapinu, kehtib sama URL-i kuju, kuid renderdamise teekond on erinev. Lovable’i Vite i18n-i juhend käsitleb seda juhtumit ja TanStack Starti seadistusjuhend selgitab SSR-i poolt põhjalikumalt.


Kuidas luua keelevalija komponent?

Liikuge sama marsruudi juurde teise lokaali parameetriga ja renderdage iga valik päris lingina.

// 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>
  );
}

Renderdage valikud ankrutena, mitte nuppudena, mis kutsuvad välja ruuteri funktsiooni. Ankrud on roomatavad, andes otsingumootoritele lisaks saidikaardile teise võimaluse teie lokaalipõhiseid marsruute avastada. Märgistage iga valik selle enda keeles, mitte lipuga: lipud tähistavad riike ja hispaania keel ei ole riik.


Kuidas hreflang-märgendeid õigesti väljastada?

Väljastage igal komplekti kuuluval lehel iga lokaali kohta üks märge, sealhulgas viide iseendale, ning lisaks x-default.

Google kontrollib, et alternatiivsed URL-id viitaksid tagasi, ning eirab märkusi, mis pole vastastikused või viitavad lehe enda kanoonilisest URL-ist eemale. Seetõttu on nende programmiliselt genereerimine ainus mõistlik lähenemine: nelja keele ja kahekümne lehe puhul tuleb käsitsi järjepidevana hoida 320 märget.

TanStack Startis looge need marsruudi head-is:

// 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}` },
      ],
    };
  },
});

Kuna märkused tuletatakse samast LOCALES massiivist, mida ruuter kasutab, uuendab keele lisamine korraga marsruute, keelevalijat ja hreflang-komplekti. Just seda omadust tuleb kaitsta: üks loend, kolm kasutajat.

Lisage samad URL-id oma saidikaardile koos xhtml:link alternatiividega ja veenduge, et teie <html lang> atribuut vastaks aktiivsele lokaalile. Atribuut lang ei mõjuta hreflangi, kuid mõjutab ekraanilugejaid ja brauseri tõlkepäringuid.


Miks ei saa käitusajal toimiv tõlkevidin seda teha?

Sest vidin tõlgib pärast seda, kui leht on juba ingliskeelsena saadetud.

Käitusajal toimiv vidin vahetab teksti brauseris pärast skripti laadimist. Roomaja saab esimese vastusena ingliskeelse DOM-i ja tõlgitud versioon tekib alles pärast kliendipoolse JavaScripti käivitumist. Mõni vidin pakub küll genereeritud hreflangiga alamdomeeni- või alamkataloogirežiimi, kuid siis kuuluvad URL-i struktuur ja märkused teenusepakkuja taristule, mitte teie hoidlasse.

Sellel sõltuvusel on hind, mis pole enam hüpoteetiline. Lovalingo, Lovable’i ehitajate seas populaarne tõlkevidin, suletakse 31. augustil 2026 ning nende enda juhised soovitavad kasutajatel üle minna projektipõhisele rahvusvahelistamisele. Kui vidin kaob, kaovad ka selle loodud keele-URL-id ja sait pöördub tagasi inglise keelele. Teie enda koodis määratletud kataloogidel ja marsruutidel sellist väljalülitit pole. Kirjutasime selle migratsiooni praktilisest poolest Lovalingo alternatiivide võrdluses.


Aga klassikaline Vite SPA tehnoloogiapinu?

URL-i struktuur on sama, renderdamine mitte.

Enne TanStack Starti üleminekut loodud Lovable’i projektid on Vite’i ja Reacti ühe lehe rakendused, mida serveeritakse staatiliste failidena ja renderdatakse brauseris. Saate endiselt marsruutida /:locale alusel, väljastada hreflangi ja hoida katalooge hoidlas. Kaotate aga garantii, et roomaja esimene bait sisaldab tõlgitud sisu.

Kui SEO on üldse lokaliseerimise põhjus, lisage lokaalipõhistele marsruutidele prerenderdamine, et igaüks neist väljastaks päris HTML-i, või kavandage üleminek serveris renderdatavale tehnoloogiapinule. Ärge lahendage seda kliendipoolselt renderdatava rakenduse peale käitusaja vidina lisamisega – nii kuhjate kaks kliendipoolset renderdamisetappi ja muudate esimese sisulise renderduse igas keeles halvemaks.


Kuidas hoida nelja lokaali omavahel sünkroonis?

Automatiseerige eraldamine ja käsitlege katalooge lähtekoodina.

Põhjus, miks lokaalipõhisest marsruutimisest loobutakse, ei ole marsruutimine. Põhjus on selles, et iga uus funktsioon lisab ingliskeelseid stringe, mida keegi ei eralda, nii et /de/ täitub aeglaselt ingliskeelsete fragmentidega ja hakkab nägema välja halvem kui saksa keele puudumine üldse. globalize.now haldab seda kihti: lisage oma Lovable’i tööruumi lovable-i18n skill ja andke Lovable’ile juhis i18n seadistada või paigaldage skill’id lokaalselt:

npx skills add globalize-now/globalize-skills

Lisage --all, et paigaldada see iga agendi jaoks. Uued stringid eraldatakse, võtmed genereeritakse, kataloogid tõlgitakse ja uuendatud PO-failid lisatakse iga Git push’i järel hoidlasse.

Hind on 20 € kuus tööruumi kohta ja sisaldab kuus 20 € väärtuses tõlkekrediiti (umbes 200 000 sõna), seejärel rakendub märgipõhine kasutustasu sama tähemärgi hinna alusel. Istme- ega keelepõhiseid tasusid ei ole, seega muudab viienda lokaali lisamine teie marsruutimise konfiguratsiooni, mitte arvet. Registreerumisel saate 5 € tõlkekrediiti ja kaarti pole vaja. Lisateavet leiate arendajatele ning AI abil loodud rakendusi tarnivatele inimestele.

Marsruutimine ja hreflang on ühe pärastlõuna töö. Nelja kataloogi täielikuna hoidmine rakenduse muutudes on osa, mis ei lõpe kunagi – ja just seda osa globalize.now automatiseerib.

globalize.now muudab rakenduse koodis olevad tekstid tõlkeks valmis lokaale failideks ja hoiab neid ajakohasena, kui sa uusi versioone välja lasid.

Proovi globalize.now tasuta