Codex, Claude Code या Cursor से एक ही प्रॉम्प्ट में अनुवादित ऐप शिप करने से पहले सात चीज़ें जाँचें: लंबी स्ट्रिंग समाती हैं या नहीं, प्लुरल फ़ॉर्म हर भाषा से मेल खाते हैं या नहीं, वेरिएबल सही-सलामत बचे या नहीं, शब्दावली एकसमान है या नहीं, टोन नेटिव स्पीकर को ठीक लगता है या नहीं, हर लोकेल में हर key मौजूद है या नहीं, और अगला फ़ीचर कभी अनुवादित होगा भी या नहीं। globalize.now AI-संचालित स्थानीयकरण इंफ्रास्ट्रक्चर है, और वन-शॉट अनुवाद के बाद हमें जो गड़बड़ियाँ दिखती हैं उनमें से ज़्यादातर यांत्रिक होती हैं, जो अच्छी ख़बर है: यांत्रिक समस्याओं को जाँचा जा सकता है।

पहला पास शायद ही कभी समस्या होता है। आज के एजेंट पढ़ने लायक़ अनुवाद तेज़ी से तैयार कर देते हैं। एक प्रॉम्प्ट में जो नहीं होता, वह है आउटपुट को सत्यापित करने वाला कोई चरण, और ये जाँचें वही चरण हैं।

क्या अनुवाद के बाद टेक्स्ट फ़िट होता है?

अक्सर नहीं, और सबसे पहले बटन टूटते हैं। अनुवाद में टेक्स्ट के आकार पर W3C का मार्गदर्शन बताता है कि सोर्स संदेश जितना छोटा होगा, उसके फैलने की संभावना उतनी ही ज़्यादा होगी, इसलिए दो शब्दों का बटन लेबल किसी पैराग्राफ़ की तुलना में अनुपात में कहीं ज़्यादा बढ़ता है। यह भी बताया गया है कि जर्मन जैसी भाषाओं में संयुक्त संज्ञाएँ (compound nouns) अगली पंक्ति में नहीं लपेटी जा सकतीं, और कुछ लिपियों को लैटिन टेक्स्ट से ज़्यादा क्षैतिज या ऊर्ध्वाधर जगह चाहिए।

JSON फ़ाइल में स्ट्रिंग का अनुवाद करने वाला एजेंट स्क्रीन कभी नहीं देखता, इसलिए उसे पता ही नहीं चलता कि "Save changes" अब बटन के एक किनारे से दूसरे किनारे तक भर गया है। अपना ऐप उस सबसे लंबी लोकेल में चलाइए जो आप शिप करते हैं, मुख्य फ़्लो में घूमिए, और कटे हुए टेक्स्ट, लपेटे गए बटन और छँटी हुई टेबल हेडर देखिए। अगर आप दाएँ-से-बाएँ (RTL) भाषाएँ सपोर्ट करते हैं, तो उनमें से किसी एक में भी यही पास कीजिए; Lovable ऐप्स के लिए अरबी और RTL गाइड दिशा (direction) की बात करती है, जो अकेले ओवरफ़्लो जाँच से नहीं पकड़ी जा सकती।

टिकाऊ समाधान लेआउट में है, अनुवाद छोटा करने में नहीं: कंटेनर को बढ़ने दें, टेक्स्ट पर निश्चित चौड़ाई न लगाएँ, और जगह बचाने के लिए संक्षिप्त रूप न बनाएँ। यह हिस्सा अपने एजेंट से करवाइए, क्योंकि यह कोड का काम है।

क्या प्लुरल फ़ॉर्म लक्षित भाषा से मेल खाते हैं?

यह जाँच जल्दी कर लें, क्योंकि यह चुपचाप फ़ेल होती है। Unicode CLDR छह प्लुरल श्रेणियाँ परिभाषित करता है: zero, one, two, few, many और other। अंग्रेज़ी में केवल one और other इस्तेमाल होते हैं। रूसी में one, few, many और other। वेल्श में छहों, और i18next के दस्तावेज़ में अरबी के लिए भी छहों प्लुरल कीज़ दिखाई गई हैं।

जो एजेंट अंग्रेज़ी की जोड़ी को रूसी या अरबी फ़ाइल में कॉपी कर देता है, वह ऐसा कैटलॉग बनाता है जो पार्स भी होता है और रेंडर भी, पर हर उस संख्या के लिए ग़लत फ़ॉर्म दिखाता है जिसे फ़ाइल में मौजूद न श्रेणी की ज़रूरत है। कोई एरर नहीं आएगा। i18next में याद रखें कि वेरिएबल का नाम ठीक count ही होना चाहिए, और दस्तावेज़ बताता है कि इसके न होने पर सादी key पर कोई फ़ॉलबैक नहीं होता। कंपोनेंट में count === 1 ? 'item' : 'items' लिखने वाले उसी एजेंट में अनुवाद शुरू होने से पहले ही यही बग मौजूद होता है; सिंटैक्स वाला पक्ष ICU MessageFormat क्या है और यह AI-जनित ऐप्स को क्यों उलझाता है में समझाया गया है।

जाँच यांत्रिक है: हर लोकेल के लिए प्लुरल कीज़ की तुलना उन श्रेणियों से करें जो उस भाषा को चाहिए।

क्या इंटरपोलेशन वेरिएबल सुरक्षित बचे?

हमेशा नहीं, और इसका फ़ैसला स्क्रिप्ट कर देती है। {{name}} या {count} जैसे इंटरपोलेशन वेरिएबल हर अनुवाद में ठीक वैसे ही मौजूद होने चाहिए जैसे लिखे गए हैं। लंबी फ़ाइल का अनुवाद करते समय एजेंट कभी-कभी वेरिएबल का शब्द बदल देते हैं, वाक्य बेहतर लगने पर किसी वेरिएबल को हटा देते हैं, या टैग के भीतर की सामग्री का अनुवाद कर देते हैं। नतीजा होता है ख़ाली जगह, सीधा-सीधा ब्रेस दिखना, या क्रैश।

हर अनुवादित स्ट्रिंग के वेरिएबल का सेट उसकी सोर्स स्ट्रिंग से मिलाइए। नीचे की यह छोटी Node स्क्रिप्ट यही करती है, और वे कीज़ भी बताती है जो अंग्रेज़ी में हैं पर किसी दूसरी लोकेल में नहीं:

import fs from "node:fs";

const [src, ...targets] = process.argv.slice(2);
const read = (f) => JSON.parse(fs.readFileSync(f, "utf8"));
const vars = (s) =>
  [...String(s).matchAll(/\{\{?\s*[\w.]+\s*\}?\}/g)].map((m) => m[0]).sort().join(",");

const base = read(src);
let problems = 0;
for (const file of targets) {
  const loc = read(file);
  for (const [key, text] of Object.entries(base)) {
    if (!(key in loc)) { console.log(file, "missing", key); problems++; continue; }
    if (typeof text === "string" && vars(text) !== vars(loc[key])) {
      console.log(file, "variable mismatch", key); problems++;
    }
  }
}
process.exit(problems ? 1 : 0);

इसे CI में node check-locales.mjs locales/en.json locales/de.json locales/ru.json के रूप में चलाइए। यह मानकर चलती है कि key फ़ाइलें सिंगल-लेवल हैं; अगर आपका कैटलॉग नेस्टेड है तो लूप को उसी हिसाब से बदल लें।

क्या शब्दावली एकसमान है?

एक ही उत्तर के भीतर तो एकसमान रहती है, पर कई उत्तरों में भटक जाती है। अगर किसी बड़े ऐप का अनुवाद कई फ़ाइलों, सेशन या बैच में बँटा है, तो कुछ भी यह तय नहीं करता कि "workspace", "project" और आपके प्रोडक्ट का नाम हर बार एक ही तरह से आएँगे। नतीजा यह कि किसी बटन पर कुछ और लिखा होता है और हेल्प पेज पर कुछ और।

शब्दों को एक बार लिख लें: प्रोडक्ट के नामों, फ़ीचर के नामों और उन शब्दों की शब्दावली (glossary) जिनका अनुवाद नहीं होना चाहिए, और अनुवाद चरण से उसे पढ़वाएँ। globalize.now कोडबेस के कन्वर्ट होते समय एक साझा glossary तैयार करता है, यानी अनुवाद शुरू होने से पहले ही शब्द डेटा के रूप में मौजूद होते हैं। टूल के बिना, एक छोटी glossary फ़ाइल जिसका उल्लेख आपके एजेंट के निर्देशों में हो, न्यूनतम ज़रूरत है; ये निर्देश कहाँ रहते हैं, यह AGENTS.md रूल्स वाली पोस्ट में दिखाया गया है।

क्या यह नेटिव स्पीकर को सही लगता है?

यह इकलौती जाँच है जो स्क्रिप्ट नहीं कर सकती। रजिस्टर, औपचारिकता और केसिंग (casing) वे जगहें हैं जहाँ वन-शॉट अनुवाद मशीनी लगते हैं: संबोधन का ग़लत स्तर, आदेश जैसे लगने वाले इम्पेरेटिव बटन, या ऐसी भाषा में कैपिटल अक्षरों की हेडलाइन जहाँ वह चिल्लाने जैसा पढ़ा जाता है।

हर स्ट्रिंग की समीक्षा न करें। आप जितने भाषा-परिवार शिप करते हैं, उनमें से हर एक के लिए एक भाषा चुनें, और किसी नेटिव स्पीकर से पहली बार चलने वाली स्क्रीन, चेकआउट या साइनअप फ़्लो और एरर संदेश पढ़वाएँ। टोन की वजह से उपयोगकर्ता इन्हीं स्क्रीन पर आपसे दूर होते हैं। उनके सुधार glossary में दर्ज कर लें, ताकि अगला रन उन्हीं से शुरू हो।

क्या हर key मौजूद है, और क्या हर स्ट्रिंग कैटलॉग तक पहुँची?

दो अलग तरह की कमियाँ स्क्रीन पर एक जैसी दिखती हैं। एक key अंग्रेज़ी में मौजूद हो सकती है और किसी लोकेल में ग़ायब, जिसे ऊपर की स्क्रिप्ट पकड़ लेती है। या कोई स्ट्रिंग कंपोनेंट में हार्डकोड रह गई हो और कैटलॉग तक कभी पहुँची ही न हो, इसलिए कोई अनुवाद उसे कवर नहीं कर सकता। एजेंट दूसरी तरह की स्ट्रिंग दिखने वाले टेक्स्ट की तुलना में attributes, टोस्ट और एरर संदेशों में ज़्यादा छोड़ते हैं; यह पैटर्न और इसे पकड़ने वाला lint नियम एजेंट हार्डकोडेड स्ट्रिंग क्यों जोड़ते रहते हैं में समझाया गया है।

ऐप को किसी ग़ैर-अंग्रेज़ी लोकेल में बदलिए और उसमें घूमकर देखिए। जो भी अंग्रेज़ी बची दिखे, वह या तो ग़ायब key है या ऐसी स्ट्रिंग जो सिस्टम में कभी आई ही नहीं, और दोनों का समाधान अलग है।

क्या अगला फ़ीचर अनुवादित होगा?

तभी, जब अनुवाद उस प्रक्रिया का हिस्सा हो जिससे कोड शिप होता है, और यही वह जाँच है जिसे एक-प्रॉम्प्ट रन पास नहीं कर सकता। प्रॉम्प्ट ने ऐप का उसी दोपहर वाला रूप अनुवादित किया था। आपका एजेंट जो अगला फ़ीचर बनाएगा, वह उन्हीं फ़ाइलों में अंग्रेज़ी में आएगा, और लोकेल एक-एक फ़ीचर करके पीछे छूटती जाएँगी। यह कैसे जमा होता जाता है, यह अनुवाद फ़ाइलें सिंक से बाहर क्यों हो जाती हैं में बताया गया है।

यहीं वन-शॉट तरीक़ा और पाइपलाइन अलग हो जाते हैं। स्थानीयकरण का डेव लूप में अपस्ट्रीम आ जाना इस स्थिति का तर्क रखता है; व्यावहारिक रूप में बात यह है कि कन्वर्ज़न एक बार होता है और बाद के बदलावों का अनुवाद वहीं होता है जहाँ वे किए जाते हैं। globalize.now के साथ आप ऐप में रिपॉज़िटरी कनेक्ट करते हैं, कोडबेस एक बार कन्वर्ट होता है, और उसके बाद पुश जॉब नई कैटलॉग यूनिट का अनुवाद करते हैं, जिनके नतीजे आपको ऐसे बदलावों के रूप में मिलते हैं जिन्हें आप रिव्यू करके मर्ज करते हैं। रनटाइम लाइब्रेरी और कैटलॉग फ़ॉर्मैट आपके ही रहते हैं। जिन टीमों के पास पहले से कोई मानव अनुवादक है, वे वह रिव्यू चरण बनाए रखती हैं; बस अब अंग्रेज़ी-ओनली कोड और रिलीज़ के बीच वही अकेला पड़ाव नहीं रह जाता।

अगर आप इसे अपनी ही स्क्रिप्ट में रखना चाहें, तो न्यूनतम ज़रूरत है ऊपर वाली स्क्रिप्ट का CI में चलना और यह नियम कि नई स्ट्रिंग कैटलॉग से होकर जाएँ। AI से बने ऐप का स्थानीयकरण कैसे करें पूरा रास्ता दिखाती है, और Claude Code गाइड उस एजेंट को विशेष रूप से कवर करती है।

शुरुआत कहाँ से करें?

आज ही अपनी मौजूदा लोकेल फ़ाइलों पर स्क्रिप्ट चलाइए; इसमें एक मिनट लगता है और यह बता देती है कि संरचना ठीक है या नहीं। फिर अपना ऐप सबसे लंबी लोकेल में खोलिए और पहली बार चलने वाले फ़्लो में घूमिए। अगर आपने AI से बना ऐप शिप किया है और चाहते हैं कि कन्वर्ज़न, अनुवाद और बाद के अपडेट हाथ से सँभालने के बजाय अपने-आप हों, तो vibe coders पेज ओवरव्यू है, डेवलपर रेफ़रेंस एजेंट सेटअप कवर करता है, और प्राइसिंग अपने अलग पेज पर है।

globalize.now आपके ऐप्लिकेशन की हार्डकोडेड कॉपी को अनुवाद-तैयार locale फ़ाइलों में बदल देता है और जैसे-जैसे आप नई रिलीज़ करते हैं, उन्हें अपडेट रखता है।

globalize.now को निःशुल्क आजमाएं