Allolev i18n-sektsioon on see, mille saate kleepida faili AGENTS.md: kümme lühikest reeglit, mis käsivad koodiagendil suunata iga kasutajale nähtava stringi läbi tõlkefunktsiooni, anda sellele funktsiooni järgi nimetatud võti, mitte kunagi liita fragmente, mitte kunagi teeselda mitmust ternary-avaldisega ning mitte kunagi puudutada genereeritud locale file'i. globalize.now on tehisintellektil põhinev lokaliseerimistaristu, nii et näeme palju agentide kirjutatud i18n-koodi ning peaaegu kõik probleemid taanduvad samale käputäiele vigadest. Iga reegel vastab ühele neist.
Selle postituse teine pool räägib sellest, kus fail enam ei tööta. Kaks arendajate enim kasutatavat koodipinda ei loe seda üldse ja ükski sõnastus seda ei paranda.
Mida peaks AGENTS.md i18n-sektsioon ütlema?
Seda plokki. Kohandage kolm failiteed ja lint-käsk oma projektile ning ülejäänu jätke samaks.
## Internationalization
- Every user-visible string goes through the translation function. That
includes JSX text, input hint text, `title`, `aria-label`, `alt`, toast and
error messages, empty states and the document `<title>`.
- The source locale is `en`. The catalog is `locales/en.json`. Add the key in
the same change that uses it.
- Keys are namespaced by feature: `checkout.summary.total`, not `total3`.
Search the catalog for an existing key before creating one.
- Never concatenate translated fragments. Use interpolation:
`t('cart.items', { count })`, not `t('cart.you_have') + count`.
- Plurals use the library's plural forms (`_one` / `_other` keys, or ICU
`{count, plural, ...}`). Never `count === 1 ? 'item' : 'items'`.
- Dates, numbers and currency go through `Intl.DateTimeFormat` and
`Intl.NumberFormat` with the active locale. Never a bare
`toLocaleString()`, never a currency symbol glued to a number.
- Do not hardcode the locale list, language names or text direction in
components. Read them from `i18n/config.ts`.
- Do not translate brand names, code identifiers, URLs or environment values.
- Do not edit locale files other than `en`. They are generated. If a
translation looks wrong, fix the source key or the glossary, not the file.
- Before finishing, run `npm run lint`. The `i18next/no-literal-string`
rule must pass.
Kümme reeglit pole juhuslik arv. Cursori enda reeglite dokumentatsioon soovitab hoida reeglid keskendununa sageli kasutatavatele mustritele ning kasutada stiilijuhise kleepimise asemel lintimist, ja Claude Code'i juhis on sama: kirjutage juhised piisavalt konkreetsed, et neid saaks kontrollida, ning hoidke fail lühike, sest pikemaks kasvades langeb nende järgimine. Neljakümnepunktilist i18n-sektsiooni loetakse vaid diagonaalis.
Miks just need kümme reeglit, mitte lihtsalt „kasuta i18n-i“?
Sest „kasuta i18n-i“ on see, mida agent juba usub tegevat, kui ta kirjutab <Button>Save changes</Button>. Ebamäärased juhised rahuldab agent oma enda arusaamaga nõuetele vastavusest. Iga allolev reegel nimetab konkreetse väljundi ja keelab selle.
Literaalid atribuutides. Agendid õpivad, et JSX-i lapselemendid vajavad tõlkimist, ning kirjutavad siis aria-label="Close" ja alt="Company logo" lihtsate stringidena, sest atribuudid näivad konfiguratsioonina, mitte tekstina. Atribuutide nimeliselt loetlemine sulgeb selle augu; üldine „tõlgi kõik“ seda ei tee.
Liitmine. t('greeting') + ' ' + name + '!' kuvatakse inglise keeles korrektselt, kuid seda ei saa tõlkida ühtegi keelde, kus nimi tuleb esimesena või kus seda käänatakse. Interpolatsioon annab tõlkijale ühe stringi ühe liigutatava muutujaga.
Ternary-mitmused. count === 1 ? 'item' : 'items' on see, mida näeme agendi kirjutamas kõige sagedamini pärast i18n-i seadistamist, ning see on vale igas keeles, kus on rohkem kui kaks mitmuse vormi. Reegel nimetab mustri, et agent oskaks seda ära tunda. Kui teie kataloog kasutab ICU-d, käsitleb süntaksit postitus mis on ICU MessageFormat ja kus see tehisintellekti loodud rakendustes kokku kukub.
Genereeritud lokaadifailid. See reegel on olemas, sest agendid on abivalmid. Saades ülesande parandada saksakeelne trükiviga, avab agent faili locales/de.json ja muudab seda, mis töötab seni, kuni järgmine tõlketöö faili allikast uuesti genereerib. Kui talle öelda, et mitte-allikafailid on genereeritud, ja näidata, kuhu päris parandus kuulub, väldib see tervet liiki vaikseid regressioone.
en muutmine samas muudatuses. Ilma selleta lisab agent t('checkout.summary.total') ja läheb edasi ning võti kuvatakse oma nime kujul, kuni keegi seda märkab. Kataloogi kirje ja selle esimene kasutuskoht kuuluvad samasse diffi.
Kust iga tööriist faili tegelikult loeb?
Sama sisu läheb olenevalt agendist erinevatesse kohtadesse ning paigutus otsustab, kas reegel on alati kontekstis või laaditakse ainult siis, kui seda vaja on.
Hoidla juurkaustas olev AGENTS.md on ühine asukoht. Formaat on tavaline Markdown ilma kohustuslike väljadeta, seda haldab Linux Foundationi alla kuuluv Agentic AI Foundation ning seda loevad Cursor, Codex, Copilot coding agent ja pikk rida teisi. Spetsifikatsioon toetab pesastatud faile, kus muudetavale failile lähim fail on ülimuslik.
Cursor loeb faili AGENTS.md otse, sh pesastatud faile, ning sellel on ka oma piiritletud formaat. UI-failidele piiritletud reegel jääb kontekstist välja seni, kuni vastav fail avatakse:
---
description: i18n rules for user-visible strings
globs: src/**/*.tsx, src/**/*.jsx
alwaysApply: false
---
(paste the Internationalization section here)
Fail peab lõppema laiendiga .mdc ja asuma kaustas .cursor/rules/; tavaline .md selles kaustas jäetakse tähelepanuta, sest sellel puudub frontmatter.
GitHub Copilot VS Code'is pakub kolme võimalust. .github/copilot-instructions.md kehtib igale vestluspäringule. Fail .github/instructions/i18n.instructions.md, mille frontmatteris on applyTo: "**/*.tsx,**/*.jsx", kehtib ainult siis, kui vastavaid faile luuakse või muudetakse. Ning juurkaustas olevat AGENTS.md loeb Local agent siis, kui säte chat.useAgentsMdFile on sisse lülitatud; alamkaustades olevad pesastatud AGENTS.md-failid on eraldi katselise sätte chat.useNestedAgentsMdFiles taga, mis on vaikimisi väljas. Copilotiga seotud käitumist käsitletakse artiklis kuidas lisada i18n GitHub Copilotiga ehitatud rakendusele.
Claude Code loeb faili CLAUDE.md ning alates versioonist v2.1.277 loeb ta juurkausta AGENTS.md ka iseseisvalt, kui projektis pole töökaustast kõrgemal ühtegi CLAUDE.md-i. Kui hoiate mõlemat, on dokumenteeritud muster @AGENTS.md-import faili CLAUDE.md alguses, et fail laaditaks vaid üks kord. Piiritlemiseks laaditakse .claude/rules/i18n.md koos frontmatteri paths:-loendiga ainult siis, kui Claude loeb vastavat faili. Claude Code'i täielik töövoog on postituses kuidas lokaliseerida rakendus, mille Claude Code genereeris.
Praktiline lahendus hoidlale, mida puudutavad mitu agenti: kümme reeglit piiritletud failis selle agendi jaoks, mida teie meeskond kõige rohkem kasutab, ning kaherealine viide failis AGENTS.md („UI stringid: vaadake i18n-reegleid failis .cursor/rules/i18n.mdc ja järgige neid“), et iga piiritlemist mittetoetav agent samuti juhise kätte saaks.
Millised koodipinnad AGENTS.md-d üldse ei loe?
Reasisesed koodisoovitused. Seda kinnitavad mõlemad tootjad ning just see on põhjus, miks reeglifail ei saa olla kogu lahendus.
Cursori reeglite KKK vastab küsimusele „Kas reeglid mõjutavad Cursor Tabi või muid tehisintellekti funktsioone?“ lihtsalt eitavalt. Reeglid annavad sisendi Agentile; Tab, mis täidab automaatselt rea, mida parajasti kirjutate, neid ei näe. VS Code'i kohandatud juhiste leht sisaldab Copilot'i kohta sama märkust: juhiseid ei arvestata redaktoris kirjutamise ajal pakutavate reasiseste soovituste puhul.
Seega pind, kus arendaja kirjutab <p>No results found</p> ja võtab vastu hallis kirjas ettepaneku, on täpselt see pind, kuhu reeglid kunagi ei jõua. Vestlus ja agendirežiim annavad stringile võtme; soovitus, mis rea lõpetas, kui te millelegi muule mõtlesite, ei anna. Tavalise töönädala jooksul koguneb koodibaasi literaale ainsast teest, mida juhisefail ei kata, ning arendaja, kes on hoolikalt reeglifaili kirjutanud, eeldab, et agent seda eirab.
Claude Code'il reasisest koodisoovituse pinda pole, kuid selle dokumentatsioon toob sama tõdemuse esile teiselt poolt: CLAUDE.md sisu on kontekst, mitte jõustatud konfiguratsioon, ning tegevuse blokeerimiseks sõltumata mudeli otsusest kasutatakse hook'i. See on õige arusaam kõigi siinsete tööriistade kohta. Juhisefailid nihutavad tõenäosusi. Need ei jõusta midagi.
Mis reegli tegelikult jõustab?
CI-s töötav lint-reegel, mis on ühe rea lisamine, kui reeglifail juba käsib agendil seda käivitada. eslint-plugin-i18next sisaldab reeglit no-literal-string; lülitage see oma komponendikaustades sisse ning JSX-is olev literaal ei saa viisakat meeldetuletust, vaid ehitus ebaõnnestub. Seadistuse, reegli valikud ja selle, miks juhis ja jõustamine on kaks eri kihti, selgitab artikkel miks Cursor lisab kõvakodeeritud stringe ka pärast i18n-i seadistamist, seega siin me neid ei korda.
Lint-kiht annab kaks asja, mida reeglifail ei suuda. See püüab kinni reasisese täienduse väljundi, sest töötab failil, mitte vestlusel. Ja see muudab agendi enda tsükli paranduseks: ülaltoodud ploki viimane reegel käsib agendil enne lõpetamist lint'i käivitada ning agent, kes näeb no-literal-string ebaõnnestumas, annab stringile samas sessioonis ise võtme.
Claude Code'i puhul on jõustamismehhanism, millele selle dokumentatsioon osutab, PreToolUse või muutmisjärgne hook, mis käivitab lint'i just kirjutatud failil. Hookid töötavad shelli käskudena kindlates punktides ja kehtivad sõltumata sellest, kas mudel otsustas reeglit järgida.
Mis saab stringidest, mis ikkagi läbi lipsavad?
Need tuleb välja tuua, anda neile võtmed olemasolevate nimeruumide järgi ja tõlkida ning just seda osa tasub automatiseerida, mitte agenti uuesti juhendada. Punane ehitus ütleb, et literaal on olemas. Keegi peab selle ikkagi võtmeks muutma, lisama faili en ja viima kõigisse teistesse lokaalidesse.
Just sellel kihil asub globalize.now. Teisendus on ühekordne ja toimub rakenduses: ühendage hoidla ning koodibaas teisendatakse üks kord, kataloog jõuab teieni pull request'ina, mille te üle vaatate. Pärast seda tõlgivad push-tööd uued kataloogiühikud nende saabudes, nii et teisipäeva PR-is lisatud võtmel on tõlked olemas juba kolmapäeva PR-is. Käitusaegne teek, kataloogi vorming ja ülaltoodud reeglifail jäävad kõik teile; arendajate viide selgitab, kuidas Cursori, Claude Code'i, Codexi ja Copilot'i agendid seadistusjärgse rolli üle võtavad, ning Cursori integratsioon on lühim läbimäng.
Kahel seotud tõrkel on omaette artiklid. Kui probleem on selles, et agent sõnastab ümber juba võtmega varustatud teksti, siis vaadake kuidas takistada tehisintellekti agentidel teie UI-teksti ümber kirjutamast – lahendus on sama lähtelokaali distsipliin kui üheksandas reeglis. Kui lokaalid on olemas, kuid lähevad pidevalt lahku, selgitab miks tõlkefailid sünkroonist välja lähevad selle taga olevat suunamisviga.
Kust alustada?
Kleepige plokk, piiritlege see oma UI-kaustadega ja lülitage no-literal-string CI-s sisse samal pärastlõunal. Seejärel vaadake nädala jooksul, mida lint-reegel kinni püüab; see ongi mõõt, kui palju oleks reeglifail iseseisvalt kunagi suutnud. Kui saadate välja tehisintellektiga ehitatud rakendust ja soovite, et kõige läbilipsanu ekstraheerimist ja tõlkimist käsitletaks, mitte ei peaks seda ise hooldama, on vibe coders'i leht ülevaade ja hinnakiri asub eraldi lehel.
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