Teie nupud, navigatsioon ja tühjad olekud on saksa keeles. Tootenimed, kategooriad ja kirjeldused on endiselt inglise keeles. See ei ole teie i18n-seadistuse viga, vaid selle piir. globalize.now on tehisintellektil põhinev lokaliseerimistaristu: see eraldab koodibaasist hardcoded string'id, genereerib võtmed ja lokaalikataloogid ning sünkroonib need iga Git push'i järel. See loeb koodi, mitte ridu, kuid sisu, mille pärast kasutajad teie rakendusse tulid, asub ridades.

Selle lahendamine on skeemiotsus, mitte tööriistaotsus. Siin on lahendus, mis peab vastu.

Miks on minu Lovable'i rakenduse kasutajaliides tõlgitud, kuid andmebaasi sisu endiselt inglise keeles?

Sest string'ide ekstraktor näeb ainult seda, mis on teie lähtefailidesse kirjutatud.

Lovable'i rakenduse lokaliseerimisel käib skanner teie komponendid läbi ja korjab välja kõik leitud sõnasõnalised string'id: "Add to cart", "No results", "Sign in". Neist saavad kataloogis sõnumi-ID-d ning kataloog tõlgitakse ja commit'itakse. See töövoog on deterministlik ja katab kasutajaliidese täielikult.

Rida see katta ei saa. products.name = 'Trail Runner' ei olnud kunagi .tsx-failis. See saabus vormi, seed-skripti või impordi kaudu ning asub Postgresis: Lovable Cloudi sisseehitatud backend'is, mis töötab Supabase'il, või teie enda ühendatud Supabase'i projektis. Ükski koodiskanner ei loe seda kunagi ning ekstraktsiooni korduv käivitamine ei muuda seda.

Nii jääb teil ingliskeelse sisu ümber tõlgitud kest. Navigatsioonis on Warenkorb, kuid selles olev toode ütleb Trail Runner, lightweight trail shoe for wet conditions. Kasutajad märkavad seda kohe ning tulemus mõjub halvemini kui tõlkimata rakendus, sest jätab pooleli jäetud mulje.

Mida loetakse Lovable'i rakenduses andmebaasis sisuks?

Kõik, mida kasutaja või administraator saab muuta ilma deploy't tegemata. Tüüpilises Lovable'i rakenduses on selleks:

  • Toote-, paketi- või kuulutuse nimed ja kirjeldused
  • Kategooria-, sildi- ja olekusildid, mis renderdatakse otsingutabelist
  • Turundustekst, mis on salvestatud pages- või sections-tabelisse
  • E-posti- ja teavituste mallid
  • Enum'i-laadsed väärtused, mida kuvate otse, näiteks status = 'pending_review'
  • Kasutajate loodud sisu, mis jäetakse tavaliselt meelega algkeelde

Viimane punkt on oluline. Ärge tõlkige kasutajate loodud sisu vaikimisi. Hispaania keeles kirjutatud arvustus peaks jääma hispaania keelde. Lokaliseerige sisu, mille olete ise loonud ja avaldanud.

Kõik muu – selle sisu ümber olev kasutajaliidese kiht – jääb teie kataloogidesse. Need kaks kogumit ei tohiks kunagi kattuda. Kui silt esineb nii otsingutabelis kui ka hardcoded string'ina, valige sellele üks asukoht ja kustutage teine, muidu avaldate sama mõiste kohta kaks erinevat saksakeelset sõna.

Kuidas Supabase'is andmebaasisisu tõlkeid salvestada?

Kasutage eraldi tõlketabelit, mille võtmeteks on rea ID ja lokaali veerg.

create table product_translations (
  product_id  uuid not null references products(id) on delete cascade,
  locale      text not null,
  name        text not null,
  description text,
  primary key (product_id, locale)
);

create index product_translations_locale_idx on product_translations (locale);

Jaapani keele lisamine on nüüd insert, mitte migratsioon. Reataseme turvapoliitikad seotakse ühe tabeliga, mitte kasvava veerukogumiga, ning puuduv tõlge tähendab puuduvat rida – seda on lihtne pärida ja selle puudumisest teavitada.

Alternatiiv on iga tõlgitava välja jaoks eraldi JSONB-veerg:

alter table products
  add column name_i18n jsonb not null default '{}'::jsonb;

-- { "en": "Trail Runner", "de": "Trail Runner", "fr": "Coureur de sentier" }

Seda on kiirem prototüüpida ja see sobib väikese, peamiselt staatilise sisu korral. Samas kaotate keelepõhised piirangud, osaliste tõlgete auditeerimine muutub ebamugavaks ning lokaliseeritud väärtuse järgi filtreerimisel või sortimisel muutub indekseerimine kulukaks.

Kolmas muster – iga keele jaoks eraldi veerg (name_en, name_de, name_fr) – on see, mida tasub vältida. Iga uus keel tähendab skeemimigratsiooni igas tabelis ning Lovable'i projektis tähendab see agendilt tootmistabelite korduvat muutmist. Kui soovite selle mustri kohta põhjalikumat käsitlust, rakendab avalik pg_i18n Postgresi laiendus tõlketabeli lähenemise vaadetena, millel on fallback juba sisse ehitatud, ning seda tasub enne skeemi lukku panemist lugeda.

Millise mustri peaksite valima?

Tõlketabeli, välja arvatud juhul, kui sisu on väga väike ja muutumatu.

Valige JSONB ainult siis, kui tõlgitavaid välju on vähem kui käputäis, teil pole vaja nende järgi filtreerida ega sortida ning te ei plaani lasta kellelgi peale enda neid muuta. Kõik muu – adminiliidesega sisu, sisu, millele lisate keeli, ja sisu, milles on rohkem kui mõnisada rida – vajab tabelit.

Kuidas pärida renderdamise ajal õiges keeles sisu?

Selgesõnalise fallback'iga andmebaasis, et rakendus ei peaks selle üle üldse mõtlema.

create or replace function products_for_locale(p_locale text)
returns table (id uuid, slug text, name text, description text)
language sql stable as $$
  select
    p.id,
    p.slug,
    coalesce(t.name, base.name)               as name,
    coalesce(t.description, base.description)  as description
  from products p
  left join product_translations base
    on base.product_id = p.id and base.locale = 'en'
  left join product_translations t
    on t.product_id = p.id and t.locale = p_locale;
$$;

Seejärel edastab väljakutse ainult lokaali ja mitte midagi muud:

const { data: products } = await supabase
  .rpc('products_for_locale', { p_locale: locale });

Selle toimimiseks pärisandmetega on vaja kahte reeglit. Esiteks coalesce lähtekeelele, mitte kunagi tühjale string'ile: poolikult tõlgitud kataloog peaks näitama ingliskeelset sisu, mitte tühje kaarte. Teiseks peab edastatav locale olema sama väärtus, mida kasutab teie marsruudi segment, ja sama väärtus, mille järgi teie kasutajaliidese kataloogid on võtmetatud. Üks lokaalide loend, kolm tarbijat: ruuter, kataloogid, andmebaas.

Just selles punktis lähevad enamik Lovable'i projekte lahku. Ruuter teab de, kataloogid loodi de-DE jaoks ja andmebaasis on read märgendiga german. Valige täpselt see BCP 47 siltide kogum, mida teie lokaalimarsruudid kasutavad, ja kohandage kõik muu sellele. Kui marsruudid pole veel seadistatud, katavad virnapõhised juhendid mõlemad Lovable'i genereeritud virnad: Vite SPA ehituse ja TanStack Starti SSR-i vaikeseadistuse.

Miks mitte lasta runtime'i vidinal andmebaasiteksti lihtsalt tõlkida?

Sest see töötab renderdatud lehel, mitte teie andmetega, ning see erinevus avaldub kolmes kohas.

JavaScripti tõlkevidin loeb DOM-i jõudva teksti ja vahetab selle tagantjärele välja. See tõesti tabab ka andmebaasiridu – see on üks asi, mida vidinad teevad ja kataloogid mitte, mistõttu tunduvad need alguses täieliku lahendusena.

Kulud on struktuursed. Tõlgitud read eksisteerivad ainult brauseriseansi ajal, mistõttu lehte indekseerivad otsingumootorid näevad lähtekeelt; Wegloti enda abikeskus ütleb, et selle JavaScripti-integratsioon ei paku SEO-eeliseid, sest tõlked renderdatakse kliendipoolselt. Parandused asuvad teie andmebaasi asemel teenusepakkuja juhtpaneelis, mistõttu välja tegelik väärtus jaguneb kahe süsteemi vahel. Lisaks toimub vahetus pärast renderdamist, mistõttu sellisel viisil loodud tõlgitud rakendused näitavad igal navigeerimisel korraks ingliskeelset teksti.

Ükski neist põhjustest ei tähenda, et lähenemine tuleks sisemise tööriista puhul täielikult kõrvale jätta. Küll aga tähendab see, et avalikku ja indekseeritavat mitmekeelset toodet ei tasu sellele üles ehitada.

Kuidas hoida need kaks kihti sünkroonis?

Kasutades üht lokaalide loendit ja üht käivitajat.

Koodikiht on automaatne. Lisage oma Lovable'i tööruumis lovable-i18n skill ja paluge Lovable'il i18n seadistada või installige see lokaalselt:

npx skills add globalize-now/globalize-skills

Seejärel käivitub ekstraktsioon ja iga push'i järel avatakse tõlke-pull request: pole juhtpaneeli sammu ega käsitsi lokaalifailide ülevaatust. See on sama töövoog, mida kirjeldatakse artiklis miks Lovable'i tõlked iga push'i järel katki lähevad.

Andmekiht kuulub teile ja vajab üht läbimõeldud ühenduskohta: iga kord, kui lisate lokaali, peaks sama loend, mille põhjal luuakse marsruudid ja kataloogid, käivitama ka tõlketabeli täitmise. Lovable’i projektis tähendab see praktiliselt seemnefunktsiooni, mille palute agendil üks kord kirjutada: see loeb lokaalide loendi ja lisab lähtekeele väärtuste põhjal puuduvad read. Puuduvad read saavad siis täidetud, mitte välja mõeldud, ning coalesce katab seni tekkinud lünga.

Ka hinnastus ei sea siin takistusi. Starteri pakett maksab 20 € kuus tööruumi kohta ja sisaldab kuus 20 € väärtuses tõlkekrediiti – umbes 200 000 sõna –, sellest suurema kasutuse eest rakendub avaldatud tähemärgipõhine hind. Kasutajapõhiseid ega keelepõhiseid tasusid ei ole, seega viienda keele lisamine maksab ainult selle tõlkimiseks kuluvate tähemärkide hinna. Registreerumisel saate 5 € tõlkekrediiti ja kaarti pole vaja. Lisateavet selle kohta, kuidas see sobitub agendipõhise arendusvirnaga, leiate vibe coders ja developers lehtedelt.

Mis juhtub, kui lokaliseerimisteenuse pakkuja tegevuse lõpetab?

Kõik, mis oli salvestatud nende serveritesse – ja mitte miski, mis oli salvestatud teie omadesse.

See pole sel kuul hüpoteetiline olukord. Lovalingo, käitusaegne tõlkekiht, mille paljud Lovable’i ehitajad kasutusele võtsid, lõpetab tegevuse 31. augustil 2026 kell 23:59 CEST. Seda kinnitab nende enda teenuse sulgemise leht; uute projektide ja tellimuste vastuvõtt on juba peatatud ning aktiivsetele klientidele valmistatakse ette säilitamiseks mõeldud ekspordifaile. Huvitav on nende enda soovitus: nad paluvad klientidel rakendada paralleelselt projektipõhist i18n-i ja eemaldada teenuse alles pärast seda, kui asendus on tootmiskeskkonnas kontrollitud.

See on kogu argument ühe lausega – teenusepakkujalt, kelle lahkumine seda tõestab. Püsiv kataloog ja product_translations tabel on mõlemad teie omand; neil ei ole teenuse olekut. Hallatav käitusaegne kiht on sõltuvus, mis kuvab teie toote teksti, ja sõltuvused saavad otsa.

Kui migreerite praegu vidinalt ära, alustage andmekihist. Kasutajaliidese stringid saab teie koodist minutitega uuesti ekstraheerida. Andmebaasis olevad tõlked, kui need eksisteerisid ainult teenusepakkuja juhtpaneelil, ei tule tagasi. Meie Lovalingo võrdlus annab ülevaate, mida enne millegi eemaldamist kontrollida.

Koodikiht on see osa, mida te ei peaks käsitsi haldama. globalize.now ekstraheerib teie stringid, genereerib kataloogid ja avab iga push’i järel tõlke pull request’i, nii et saate andmekihi üks kord üles ehitada ja seejärel unustada.

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