UI teksts paliek konsekvents, kad katrs lietotājam redzamais teksts atrodas vienā katalogā repozitorijā, tiek izmantots ar atslēgu palīdzību un mainās tikai caur pārskatītu diffu. Tā ir tā pati disciplīna, ko jau piemērojat loģikai, tikai attiecināta uz formulējumiem. Viss pārējais šajā lapā ir prakse, kas to nostiprina.

Šis ir praktiskais ceļvedis. Arhitektūra, kas tam pamatā, un arguments, kāpēc kodbāzei jābūt produkta teksta patiesības avotam, ir aprakstīts rakstā uz kodu balstīts produkta teksts. Lasiet to, ja vēlaties zināt, kāpēc. Lasiet tālāk, ja vēlaties zināt, kā.

Kur jāatrodas UI tekstam?

Vienā kataloga failā katrai avota valodai, repozitorijā, blakus kodam, kas to attēlo. Ne izklājlapā, ne dizaina failā, ne wiki lapā, kas marta mēnesī bija precīza. Katalogs ir vieta, kur raugās izstrādātājs, pārskatītājs, tulkotājs un kodēšanas aģents, kad vēlas uzzināt, ko ekrānā raksta.

Praktiskie noteikumi, kas no tā izriet:

  • Viens katalogs, viena avota lokalizācija. Viens en.json (vai .po, .ftl, .strings, ko nu jūsu i18n bibliotēka lasa) ir teksta pamatversija. Ja monorepozitorijā ir vairākas lietotnes, katrai ir savs katalogs, bet kopīgie teksti atrodas kopīgā katalogā, ko importē abas. Tā jūs izvairāties no diviem failiem, kas var saturēt vienu un to pašu ziņojumu.
  • Grupējiet pēc ekrāna vai funkcijas, nevis pēc komponenta. Atslēgas, piemēram, checkout.summary.total, noveco labāk nekā SummaryCard.totalLabel, jo komponenti tiek pārdēvēti un sadalīti, bet ekrāns un ziņojums paliek.
  • Nosauciet atslēgu pēc ziņojuma, nevis pēc formulējuma. checkout.submit pārdzīvo izmaiņu no “Place order” uz “Buy now”. checkout.placeOrderButton to nepārdzīvo, un neatbilstība starp atslēgu un tekstu ir tas, kas vēlāk liek pārskatītājam domāt, ka tie ir divi dažādi teksti.
  • Turiet katalogu tajā pašā pull requestā, kur ir kods, kas to izmanto. Teksts, kas pievienots vienā PR, un tā komponents citā ir teksts, kas tiks palaists garām, aizmirsts vai dublēts.

Ja jūsu teksti joprojām ir burtiski komponentu iekšienē, katalogs ir pirmais, ko veidot. To darīt ar rokām ir atsevišķs projekts, un tieši tāpēc ir vērts pieslēgt repozitoriju un ļaut pārveidošanu paveikt automātiski, kā aprakstīts tālāk.

Kāpēc atsaukšanās uz atslēgu ir labāka par burtiskā teksta meklēšanu?

Jo atslēga var norādīt tikai uz vienu tekstu, bet burtisku tekstu var uzrakstīt tik daudzos veidos, cik ir izstrādātāju. “Sign in”, “Sign In”, “Log in” un “Login” meklēšanas rīkam ir četri teksti, bet lietotājam — viens nodoms. Kad katrs komponents izsauc t("auth.signIn"), jautājums par to, kurš formulējums ir pareizais, tiek atrisināts vienreiz, vienā vietā, un atbilde attiecas uz visām vietām, kur atslēga tiek izmantota.

Divi ieradumi nodrošina, ka tas darbojas:

  • Vispirms izmantojiet esošo, tad pievienojiet jaunu. Pirms atslēgas izveides meklējiet katalogā šo ziņojumu. Ja common.cancel jau pastāv, jauna dialog.cancelButton ar to pašu tekstu ir novirzes sākums, nevis nekaitīgs dublikāts. Abas tiks rediģētas atsevišķi, tiklīdz kāds mainīs vienu no tām.
  • Nesaliekiet tekstus kopā. t("cart.items") + " " + count rada tekstu, ko neapraksta neviena kataloga rinda. Izmantojiet savas bibliotēkas interpolāciju un daudzskaitļa formas, lai viss teikums būtu viena pārskatāma vienība.

Izņēmums, pie kura cilvēki mēdz vērsties, ir “šis teksts parādās tikai vienreiz, tāpēc burtisks teksts der”. Šodien tas parādās vienreiz. Komponents tiks nokopēts, ekrānam parādīsies līdzīgs ekrāns, un burtiskais teksts ceļos līdzi, bet pēc tam sāks atšķirties.

Kā pārskatīt teksta izmaiņas pull requestā?

Pret mainītu kataloga rindu izturieties tāpat kā pret mainītu funkcijas signatūru: tā ir lieta, ko pārskatītājs izlasa, apšauba un apstiprina. Tieši šī prakse konsekvences jautājumu pārvērš no atmiņas problēmas par pārskatīšanas problēmu, un pārskatīšana ir vienīgais brīdis, kad kāds noteikti pievērš uzmanību.

Kas liek kataloga pārskatīšanai darboties:

  • Formulējuma izmaiņa ir sava rinda diffā. Tas ir spēkā tikai tad, ja teksts ir katalogā. Formulējuma izmaiņa komponentā arī ir diff rinda, taču tā paslēpjas starp loģikas izmaiņām, un to izlasa pavirši kā “tikai tekstu”.
  • Novirziet kataloga izmaiņas teksta īpašniekam. CODEOWNERS ieraksts kataloga ceļam nozīmē, ka tas, kam pieder formulējumi — produkta pārstāvis, satura dizainers vai izstrādātājs, kuram tas rūp visvairāk —, tiek pieprasīts katrai izmaiņai tajā. Viss pārējais PR iet cauri parastajai pārskatīšanai.
  • Uzdodiet trīs jautājumus par katru mainīto rindu. Vai šis ir apstiprinātais termins šim objektam? Vai tas atbilst apkārtējiem tekstiem toņa un burtu reģistra ziņā? Vai atslēgas nosaukums joprojām raksturo ziņojumu? Pārskatītājs, kas uzdod šos trīs jautājumus, noķer lielāko daļu no tā, ko stila vadlīnijas ir paredzētas novērst.
  • Noraidiet klusas pārdēvēšanas. PR, kas maina auth.signIn no “Sign in” uz “Log in” bez paskaidrojuma, ir teksta lēmums, ko pieņēmis tas, kurš nejauši to rediģēja. PR aprakstā jāpievieno teikums ar iemeslu, citādi izmaiņa jāatceļ.

Šai problēmai ir sava nosaukums. Teksta novirze ir lietotājam redzama teksta atšķiršanās no sava apstiprinātā avota dažādās saskarnēs un laika gaitā, ja nav viena patiesības avota, ar kuru to salīdzināt. Kas ir teksta novirze aplūko cēloņus; kataloga pārskatīšana diffā ir prakse, kas aptur lielāko daļu no tiem.

Kā nepieļaut jaunus burtiski ierakstītus tekstus?

Panāciet, lai jauna burtiski ierakstīta virkne izraisa būvēšanas kļūdu. Noteikumi un pārskatīšana pieķer to, ko cilvēki atceras meklēt. Lint noteikums pieķer pārējo katrā pull requestā, un nevienam nekas nav jāatceras.

Uzstādīšana ir neliela:

  • Ieslēdziet no-literal-string noteikumu. eslint-plugin-i18next piedāvā tādu JavaScript un TypeScript projektiem. Attieciniet to uz JSX tekstu un lietotājam redzamiem atribūtiem, piemēram, ievades mājieniem, title, aria-label un alt, un atzīmējiet testu failus un Storybook stories kā izņēmumus, lai noteikums saglabātu uzticamību.
  • Palaidiet to tur, kur notiek sapludināšana. Pre-commit hook ir ērts; CI solis ir tas, kas skaitās, jo tas darbojas pull requestā neatkarīgi no tā, vai autora redaktors bija sakonfigurēts.
  • Pievienojiet pārbaudi neizmantotām un trūkstošām atslēgām. Lielākajai daļai i18n bibliotēku ir papildrīks, kas uzskaita atslēgas, uz kurām atsaucas kods, bet kuru nav katalogā, un atslēgas katalogā, uz kurām nekur neatsaucas. Palaidiet to arī CI. Neizmantotās atslēgas ir vieta, kur slēpjas novecojuši formulējumi.
  • Sāciet stingri, pēc tam atļaujiet izņēmumus ar komentāru. Noteikums, kas izslēgts visai components/ mapei, nav noteikums. Noteikums, kas izslēgts vienā rindā ar norādītu iemeslu, ir dokumentācija.

Komandām, kas izmanto AI kodēšanas rīkus, tas ir vēl aktuālāk, jo rīki ģenerē komponentus no lokālā konteksta un līdzi atved burtiski ierakstītus tekstus. Kāpēc Cursor AI turpina pievienot burtiski ierakstītus tekstus detalizēti apskata lint noteikumu, tostarp trīs līmeņu risinājumu: noteikumu failu, linteri un CI.

Kas jāiekļauj teksta stila vadlīnijās izstrādātājiem?

Īss fails repozitorijā, kas ietilpst vienā ekrānā, nosaka balsi, nofiksē terminus un norāda, kur jāliek teksti. Garas stila vadlīnijas dzīvo wiki un tiek izlasītas vienreiz. Īsas dzīvo blakus kodam, un cilvēki un rīki tās lasa katru reizi, kad tiek pievienots teksts.

Strādājošs COPY.md (vai sadaļa jūsu esošajā contributor ceļvedī) aptver:

  1. Balss trijos teikumos. Kā produkts skan, cik formāli tas ir, vai tas uzrunā “jūs” vai runā par “lietotāju”. Pietiekami, lai izbeigtu lielāko daļu strīdu.
  2. Termini, kas nekad nemainās. Produkta nosaukums katrai funkcijai, darbības vārdi pamatdarbībām (vai “Save” vai “Update”? “Delete” vai “Remove”?) un vārdi, kurus esat nolēmuši neizmantot.
  3. Burtu reģistra un pieturzīmju noteikumi. Teikuma reģistrs vai virsraksta reģistrs pogās un virsrakstos, vai padomos lietot punktus, kā tiek rakstīti skaitļi un datumi.
  4. Kur teksti ieiet un kā tiek nosauktas atslēgas. Kataloga ceļš, grupēšanas noteikums, atslēgu nosaukšanas noteikums un “meklē, pirms pievieno”.
  5. Ko darīt, ja neesat pārliecināts. Kam jautāt vai kuru atslēgu pa to laiku izmantot atkārtoti.

Turiet to repozitorijā, lai noteikumu fails varētu uz to norādīt, pārskatītājs varētu uz to atsaukties komentārā, un kodēšanas aģents varētu to izlasīt, pirms raksta jaunu uzrakstu.

Kā neļaut AI kodēšanas aģentiem izjaukt konsekvenci?

Dodiet aģentam patiesības avotu, ko lasīt, un barjeru, kas to pieķer, ja tas to neievēro. Aģents, kas ģenerē formu, bez vilcināšanās uzrakstīs “Submit” vienā ekrānā un “Send” nākamajā, jo katrs bija lokāli visticamākais vārds. Tā nav nolaidība; tam vienkārši nav nekā, ar ko saskaņoties.

Divi soļi atrisina lielāko daļu. Pirmkārt, noteikumu fails (AGENTS.md, .cursor/rules, CLAUDE.md, ko nu jūsu rīki lasa), kas nosaka: lietotājam redzamais teksts iet katalogā, izmantojiet esošās atslēgas un izlasiet COPY.md, pirms rakstāt uzrakstu. Otrkārt, lint noteikums no iepriekšējās sadaļas, jo noteikumu fails samazina minēšanu, bet lint noteikums noķer minējumus, kas tika cauri.

Tas ir viss, ko šī lapa saka par aģentiem. Konkrētā problēma, kad aģents pārformulē jau esošus tekstus, un kā šo izmaiņu padarīt redzamu, nevis kluso, ir atsevišķa tēma: kā neļaut AI kodēšanas aģentiem pārrakstīt jūsu UI tekstu.

Kur šeit iederas lokalizācija?

Konsekvence un lokalizācija balstās uz vienu un to pašu — saskaņotu avotu, tāpēc katalogs, kas nodrošina vienu, nodrošina arī otru. Komanda, kas nespēj pateikt, kurš no trim formulējumiem ir apstiprinātais, nespēj pareizi iztulkot nevienu no tiem. Sakārtojiet avotu, un tulkojums kļūst par kataloga atvasinājumu, nevis atsevišķu projektu ar savu patiesības versiju.

Praktiski tas nozīmē, ka katalogs, ko izveidojāt konsekvencei, jau ir fails, ar kuru strādā tulkotājs vai tulkošanas rīks. Katra atslēga saņem savus ekvivalentus visās mērķa valodās, tiek lietoti tie paši atslēgu nosaukumi, un formulējuma izmaiņa avota katalogā ir redzama kā izmaiņa, kurai tulkojumiem jāseko. Ja tulkojumi tiek atstāti atpalikt no avota, rodas problēmu klase, kas aprakstīta rakstā kāpēc tulkojumu faili zaudē sinhronizāciju, un risinājums ir tā pati disciplīna: viens katalogs, atslēgas, izmaiņas diffā.

Kur iederas globalize.now

globalize.now ir uz kodu orientēta teksta pārvaldības sistēma ar iebūvētu lokalizāciju, un katra šajā lapā aprakstītā prakse ir tas, ko tā sagaida no jūsu repozitorija. Jūs lietotnē pieslēdzat GitHub vai GitLab repozitoriju. Skenēšana noskaidro, kas tur ir. Ja teksti ir burtiski ierakstīti komponentos, vienreizēja pārveidošana pārvieto tos aiz atslēgām katalogā un pievieno i18n iestatījumus, ja to nav. Ja jau izmantojat next-intl, react-i18next, i18next vai Lingui, tā strādā ar to, kas jums ir. Rezultāts nonāk kā pull request savā atzarā, tāpēc pirmais katalogs iziet tieši to pārskatīšanu, kas aprakstīta iepriekš. Pēc tam jaunos avota tekstus, ko pievienojat, iztulko push darbi, kas atver pull requestu ar rezultātu. Repozitorijs paliek vienīgais patiesības avots.

Mēs virzāmies uz to, lai tā pati disciplīna darbotos visā mārketinga vietnē, mērķlapā un produktā no viena avota, lai funkcija tiktu aprakstīta vienādi visur, kur lietotājs ar to saskaras. Tas ir virziens, uz kuru ejam, nevis kaut kas, ko var iegādāties šodien. Cenas ir cenu lapā.

Kontrolsaraksts, ko varat ieviest šonedēļ

  1. Izveidojiet vienu katalogu katrai avota valodai repozitorijā un nolemiet par atslēgu nosaukšanas noteikumu.
  2. Pārvietojiet tekstus no ekrāniem, ar kuriem strādājat visbiežāk; atsaucieties uz tiem ar atslēgām.
  3. Ieslēdziet no-literal-string lint noteikumu, attiecinātu uz lietotājam redzamu tekstu, un palaidiet to CI.
  4. Pievienojiet CODEOWNERS rindu kataloga ceļam.
  5. Uzrakstiet COPY.md: balss, fiksēti termini, burtu reģistra noteikumi, kur novietojami teksti. Viens ekrāns.
  6. Norādiet sava aģenta noteikumu failā uz katalogu un uz COPY.md.
  7. Pārskatīšanas laikā noraidiet jebkuras formulējuma izmaiņas, kurām PR aprakstā nav norādīts pamatojums.

Ja otrais solis izskatās pēc mēneša darba, pieslēdziet repozitoriju, izlasiet tā piedāvāto plānu un pārskatiet izmaiņu pieprasījumu (pull request), ko tas atver.

globalize.now pārvērš burtiski ierakstītus lietotnes tekstus tulkošanai gatavos lokalizācijas failos un pastāvīgi tos atjaunina līdz ar katru jauno versiju.

Izmēģiniet globalize.now bez maksas