Nes jūsų i18n sąranka gyvuoja jūsų galvoje ir konfigūracijoje, o ne kode, kurį mato agentas. Cursor iš naujo generuoja komponentą pagal priešais esantį kontekstą, o paprastas JSX tekstas yra greičiausiai veikiantis sprendimas. Saugykloje nėra nieko, kas tam prieštarautų, todėl tekstinė reikšmė patenka į leidimą. globalize.now — AI pagrįsta lokalizacijos infrastruktūra, uždaranti šį ciklą: ji išgauna naujas eilutes, sugeneruoja raktus ir per kiekvieną Git push sinchronizuoja vertimus.
Tai problema, apie kurią niekas neįspėja. i18n sąranką galima atlikti per vieną popietę. Tikroji problema — išlaikyti ją veikiančią, kai agentas komponentus perrašo du kartus per dieną.
Kodėl po i18n sąrankos Cursor vis dar prideda kietai įrašytas eilutes?
Vienu metu galioja trys dalykai, kurie kartu garantuoja, kad tekstas prasprūs.
Agentas mato failą, o ne konvenciją. Kai paprašote Cursor pridėti nustatymų skydelį, jis perskaito redaguojamą komponentą ir galbūt kelis gretimus failus. Jūsų lokalės katalogas, vardų erdvių schema ir taisyklė, kad kiekviena naudotojui rodoma eilutė turi būti perduodama per vertimo funkciją, nepatenka į šį langą, nebent juos ten įtraukiate.
Neišverstas tekstas yra statistiškai numatytasis pasirinkimas. Didžioji dalis bet kurio modelio mokymo duomenyse esančio React kodo tekstines reikšmes rašo tiesiogiai. Kai agentas renkasi labiausiai tikėtiną kitą mygtuko etiketės žetoną, Save changes vien dėl dažnio nugali t('settings.save'). Jūs prašote jo kiekvieną kartą rinktis retesnį šabloną, tačiau nesuteikiate jokio grįžtamojo ryšio, jei jis to nepadaro.
Niekas nesugenda. Tai lemiamas veiksnys. Kietai įrašyta eilutė praeina tipų tikrinimą. Projektas sukompiliuojamas. Ji atvaizduojama. Testai praeina. Niekur jūsų procese nėra raudono ženklo, įspėjančio, kad naudotojas Vokietijoje netrukus pamatys anglišką pranešimą. Defektas lieka nematomas, kol kas nors nepersijungia į kitą lokalę ir nepradeda slinkti.
Palyginkite tai su trūkstamu importu ar netinkamu props tipu — agentas apie juos gauna pranešimą ir ištaiso per kelias sekundes. Neišverstas tekstas yra vienintelė klaidų klasė, kurią jūsų įrankių grandinė tyliai priima, todėl būtent ji ir kaupiasi.
Kurios eilutės prasprūsta dažniausiai?
Tos, kurios pridėtos paskiausiai ir sulaukė mažiausiai dėmesio.
Peržvelkite bet kurią AI padedamą kodų bazę, kuri nuo pradžių buvo daugiakalbė, ir likusį anglišką tekstą rasite nuspėjamose vietose:
- Klaidų ir sėkmės pranešimai, ypač tie, kurie pridėti taisant su kita problema nesusijusią klaidą.
- Tuščios būsenos ir įkėlimo tekstai, kurie parašomi kartą ir daugiau niekada neperžiūrimi.
- Formų validavimo pranešimai, dažnai sugeneruojami tiesiogiai schemoje.
- Prieinamumo atributai:
aria-label,alt,title. - Patvirtinimo dialogai ir destruktyvių veiksmų tekstai.
- Bet kas, kas yra
catchbloke.
Šablonas nuoseklus. Pagrindiniai scenarijai išverčiami, nes juos peržiūrite. Kraštiniai atvejai lieka kietai įrašyti, nes niekas jų neatidaro pasirinkęs antrą lokalę.
Yra ir antro lygio šios problemos versija. Kai agentas šalia jau išversto kodo prideda tekstinę reikšmę, jis kartais „geranoriškai“ sugalvoja raktą, neatitinkantį jūsų vardų erdvių schemos, todėl viename faile turite errors.saveFailed, o kitame — settings_save_error. Dabar turite ir neišverstų eilučių, ir suskaidytą raktų erdvę. Jei dar tik pradedate šį kelią, mūsų vadove apie AI sugeneruotos programos lokalizavimą aprašytas pradinis sutvarkymas.
Ar .cursor/rules arba AGENTS.md gali tai sustabdyti?
Jie padeda, todėl tokį failą verta parašyti, tačiau tai yra gairės, o ne priverstinis vykdymas.
Instrukcijų failų sluoksnis neseniai tapo standartizuotas. AGENTS.md 2025 m. pradėjo veikti kaip nuo tiekėjo nepriklausoma konvencija, o dabar jį prižiūri „Agentic AI Foundation“ prie „Linux Foundation“. Jį savaime perskaito Cursor, Codex, Copilot, Gemini CLI, Aider, Windsurf ir Zed, todėl vienas failas saugyklos šaknyje pasiekia kiekvieną jūsų komandos naudojamą agentą. Cursor taip pat palaiko aprėpties projektų taisykles kaip .mdc failus kataloge .cursor/rules/; jų antraštės valdo aprašą, failų glob šablonus ir tai, ar taisyklė taikoma visada. Praktinė 2026 m. sąranka — AGENTS.md šaknyje dėl perkeliamumo ir aprėpties Cursor taisyklės ten, kur automatinis pritaikymas iš tiesų naudingas.
Veikiantis i18n blokas galėtų atrodyti taip:
## Internationalization
- Never write user-facing text as a literal in JSX or in a string passed to a UI component.
- All user-facing text goes through the translation function from `next-intl`.
- Keys follow `feature.element.state` in lowerCamelCase, e.g. `settings.save.error`.
- Add the English value to `messages/en.json` only. Never hand-edit other locale files.
- This includes toasts, empty states, validation messages, `aria-label`, `alt` and `title`.
Tai pastebimai sumažins prasprūstančių eilučių skaičių. Tačiau iki nulio jo nesumažins, nes taisyklės failai konkuruoja dėl dėmesio su visa kita konteksto lange, o ilgos agento sesijos nukrypsta. Vertinkite šį sluoksnį kaip dažnio mažinimo priemonę, o ne garantiją.
Kaip priversti, kad dėl neišverstos eilutės projektas nesusikompiliuotų?
Pridėkite lint taisyklę, kuri JSX tekstinę reikšmę laikytų klaida, ir paleiskite ją CI procese.
Standartinis pasirinkimas — eslint-plugin-i18next taisyklė no-literal-string. Pagal numatytuosius nustatymus ji tikrina paprastą tekstą JSX žymėjime, o ne kiekvieną failo tekstinę reikšmę. Dėl to ją galima naudoti tikroje kodų bazėje, o ne susidurti su klaidingų teigiamų rezultatų siena. Ji palaiko reguliariosiomis išraiškomis aprašomus ignoravimo šablonus, saugių funkcijų iškvietimų išimtis ir tik žymėjimui skirtą režimą.
Pradinė konfigūracija:
// eslint.config.js
import i18next from 'eslint-plugin-i18next';
export default [
{
files: ['**/*.{jsx,tsx}'],
plugins: { i18next },
rules: {
'i18next/no-literal-string': [
'error',
{
markupOnly: true,
ignoreAttribute: ['data-testid', 'className'],
ignore: ['^[0-9]+$', '^\\s*$'],
},
],
},
},
];
Paleiskite ją savo procese, ne tik redaktoriuje:
npx eslint . --max-warnings=0
Dabar nematomas defektas turi raudoną žymą. Agentas gauna tokį patį grįžtamąjį ryšį apie neišverstą eilutę, kokį jau gauna apie tipų klaidą, todėl gali pats ištaisyti klaidą toje pačioje sesijoje, užuot palikęs ją aptikti kitos lokalės naudotojui. Jei norite išsamiau sužinoti, kaip nuo nulio prijungti i18n prie Cursor projekto, skaitykite mūsų 15 minučių Cursor ir Next.js vadovą ir Cursor integracijos puslapį.
Kodėl nepakanka taisyklės, dėl kurios projektas nesusikompiliuoja?
Nes raudonas projekto kūrimo rezultatas parodo, kad eilutė egzistuoja. Jis jos neišverčia.
Suveikus taisyklei, kažkas vis tiek turi parinkti raktą, atitinkantį esamas vardų erdves, pridėti anglišką šaltinio reikšmę ir parengti kitas lokalės. Vienam kūrėjui, kuris projektą išleidžia kelis kartus per dieną, šis darbas atidedamas. Jei atidėsite pakankamai ilgai, sąžiningas sprendimas taps failo įtraukimas į ignoruojamų failų sąrašą — ir grįšite į pradinę padėtį, tik su papildoma konfigūracija.
Būtent ši spraga iš išspręstos problemos sukuria pasikartojančią skolą. Pirmasis ir antrasis sluoksniai keičia tai, kaip dažnai problema atsiranda ir kaip greitai apie ją sužinote. Nė vienas iš jų neatlieka paties darbo.
Kaip atrodo trijų sluoksnių sąranka?
Instrukcijos, kontrolė, automatizavimas. Kiekvienas sluoksnis pagauna tai, ko nepastebėjo ankstesnis.
Pirmasis sluoksnis — instrukcijos. Įrašykite i18n bloką į AGENTS.md saugyklos šaknyje ir pridėkite aprėpties .cursor/rules/i18n.mdc su glob šablonais komponentų katalogams. Kaina: penkiolika minučių vieną kartą. Poveikis: iš pradžių parašoma mažiau kietai įrašytų eilučių.
Antrasis sluoksnis — kontrolė. Įjunkite no-literal-string ir nustatykite, kad dėl jo CI procesas nepavyktų. Kaina: popietė, skirta ignoravimo šablonams suderinti esamoje kodų bazėje. Poveikis: jokia tekstinė reikšmė nepatenka į pagrindinę šaką nepastebėta, o agentas gali pats pasitaisyti.
Trečiasis sluoksnis — automatizavimas. Leiskite išgavimui, raktų kūrimui ir vertimui vykti be jūsų įsitraukimo. Būtent šį sluoksnį suteikia globalize.now. Jis veikia virš jūsų i18n vykdymo aplinkos, o ne ją pakeičia: next-intl arba i18next vis tiek atvaizduoja eilutes. globalize.now aptinka naują kietai įrašytą tekstą, sugeneruoja raktus pagal jūsų projekte jau naudojamas vardų erdves, išverčia juos į visas sukonfigūruotas lokales ir per kiekvieną Git push įrašo atnaujintus lokalės failus atgal į saugyklą. Nustatykite vieną kartą — prijunkite saugyklą prie globalize.now — ir nebeliks rankinio veiksmo, kurį būtų galima praleisti. Taip pat galite jį įdiegti į savo agentą naudodami:
npx skills add globalize-now/globalize-skills
Planai prasideda nuo 5 € per mėnesį; į 20 € kainuojantį „Starter“ planą kas mėnesį įtraukta 20 € vertimo kredito — maždaug 200 000 žodžių. Už įtrauktą kiekį viršijantį naudojimą mokama tuo pačiu tarifu už simbolį. Nėra mokesčių už naudotojų skaičių ar kalbą, o užsiregistravus suteikiamas 5 € vertimo kreditas; kortelės nereikia. Daugiau techninės informacijos rasite kūrėjams skirtame puslapyje, o trumpesnę versiją žmonėms, kuriantiems su AI įrankiais, — vibe coderių puslapyje.
Trijų sluoksnių esmė ta, kad nė vienas iš jų nepriklauso nuo to, ar jūsų disciplina išliks per šimtą agento sesijų. Taisyklių failas sumažina dažnį, lint taisyklė padaro klaidas aiškiai matomas, o sinchronizavimas leidžia ištaisyti problemą be papildomų pastangų. Būtent šis derinys padeda daugiakalbei programai išlikti daugiakalbei, kol agentas ją nuolat perrašo.
Jūsų i18n sąranka nėra trapi dalis. Trapi yra grandinė tarp agento parašytos eilutės ir jos patekimo į lokalės failą. globalize.now uždaro šią grandinę per kiekvieną push.
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