क्योंकि आपका i18n setup आपके दिमाग और config में रहता है, उस code में नहीं जिसे agent देख रहा है। Cursor अपने सामने मौजूद context से component दोबारा generate करता है, और plain JSX text काम करने वाला सबसे तेज़ विकल्प है। Repo में ऐसा कुछ नहीं होता जो उसे रोके, इसलिए literal ship हो जाता है। globalize.now AI-powered localization infrastructure है जो इस loop को पूरा करता है: यह नई strings extract करता है, keys generate करता है और हर Git push पर translations sync करता है।
यह वह failure mode है जिसके बारे में कोई आपको चेतावनी नहीं देता। i18n setup करना एक दोपहर का काम है। Agent के दिन में दो बार components rewrite करने के दौरान setup को बनाए रखना ही असली समस्या है।
i18n setup होने के बाद Cursor hardcoded strings जोड़ता क्यों रहता है?
तीन बातें एक साथ सच हैं और मिलकर यह leak लगभग तय कर देती हैं।
Agent को convention नहीं, file दिखाई देती है। जब आप Cursor से settings panel जोड़ने को कहते हैं, तो वह edit किए जा रहे component और शायद उसके आसपास के कुछ components पढ़ता है। आपकी locale directory, namespace scheme और हर user-facing string को translation function से गुजारने का नियम उस window में नहीं होते, जब तक आप उन्हें वहाँ न रखें।
Untranslated text statistical default है। किसी भी model के training data में React का भारी बहुमत strings को inline लिखता है। जब agent button label के लिए सबसे संभावित अगला token चुन रहा होता है, तो sheer frequency के कारण Save changes, t('settings.save') पर भारी पड़ता है। आप उससे हर बार कम प्रचलित pattern चुनने को कह रहे हैं, और अगर वह ऐसा न करे तो कोई feedback भी नहीं मिलता।
कुछ भी fail नहीं होता। यही निर्णायक बात है। Hardcoded string type-check हो जाती है। Build सफल होता है। वह render होती है। आपके tests pass हो जाते हैं। आपके pipeline में कहीं कोई red mark नहीं आता जो बताए कि Germany का कोई user अभी English toast देखने वाला है। यह defect तब तक अदृश्य रहता है, जब तक कोई locale बदलकर scroll नहीं करता।
इसकी तुलना missing import या गलत prop type से करें, जिन पर agent को कुछ ही seconds में correction मिल जाता है। Untranslated text वह एक bug class है जिसे आपका toolchain चुपचाप स्वीकार कर लेता है—इसलिए यही bug class जमा होती जाती है।
कौन-सी strings सबसे अधिक leak होती हैं?
वे strings जो सबसे अंत में जोड़ी जाती हैं और जिनकी सबसे कम समीक्षा होती है।
किसी भी ऐसे AI-assisted codebase को देखें जो multilingual के रूप में शुरू हुआ था। बची हुई English आमतौर पर इन predictable जगहों पर मिलती है:
- Error और success toasts, खासकर वे जिन्हें किसी unrelated bug को ठीक करते समय जोड़ा गया हो
- Empty states और loading text, जिन्हें एक बार लिखा जाता है और फिर कभी review नहीं किया जाता
- Form validation messages, जो अक्सर schema के अंदर inline generate किए जाते हैं
- Accessibility attributes:
aria-label,alt,title - Confirmation dialogs और destructive-action copy
catchblock के अंदर मौजूद कोई भी चीज़
Pattern लगातार एक जैसा रहता है। आपके primary flows translate हो जाते हैं क्योंकि आप उन्हें देखते हैं। Edges hardcoded रह जाते हैं क्योंकि कोई उन्हें दूसरी locale में खोलता ही नहीं।
इसका एक second-order version भी है। जब agent पहले से translated code के पास कोई literal जोड़ता है, तो कभी-कभी वह “मददगार” बनकर ऐसा key बना देता है जो आपकी namespace scheme से मेल नहीं खाता। नतीजा यह होता है कि एक file में errors.saveFailed और दूसरी में settings_save_error होता है। अब आपके पास untranslated strings के साथ fragmented key space भी है। अगर आप इस journey के शुरुआती चरण में हैं, तो AI-generated app का स्थानीयकरण करने वाली हमारी guide initial cleanup को कवर करती है।
.cursor/rules या AGENTS.md इसे रोक सकते हैं?
वे मदद करते हैं और आपको एक लिखना चाहिए, लेकिन वे enforcement नहीं, guidance हैं।
Instruction-file layer को हाल ही में standardize किया गया है। AGENTS.md की शुरुआत 2025 में vendor-neutral convention के रूप में हुई थी और अब Linux Foundation के अंतर्गत Agentic AI Foundation इसकी देखरेख करता है। Cursor, Codex, Copilot, Gemini CLI, Aider, Windsurf और Zed इसे native रूप से पढ़ते हैं। इसका मतलब है कि repo root की एक file आपकी team द्वारा इस्तेमाल किए जाने वाले हर agent तक पहुँचती है। Cursor scoped project rules को भी .mdc files के रूप में .cursor/rules/ के अंतर्गत support करता है; frontmatter description, file globs और rule के हमेशा लागू होने को नियंत्रित करता है। 2026 में practical setup यह है कि portability के लिए root पर AGENTS.md रखें और जहाँ auto-attach उपयोगी हो वहाँ scoped Cursor rules जोड़ें।
एक workable i18n block कुछ ऐसा दिखता है:
## 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`.
इससे leak rate में स्पष्ट कमी आएगी। लेकिन यह उसे शून्य नहीं करेगा, क्योंकि rule files context window में मौजूद बाकी सभी चीज़ों के साथ attention के लिए compete करती हैं और लंबे agent sessions में drift होता है। इस layer को frequency कम करने वाला उपाय समझें, guarantee नहीं।
Untranslated string को build fail कराने के लिए क्या करें?
ऐसा lint rule जोड़ें जो JSX में मौजूद literal को error माने, फिर उसे continuous integration में चलाएँ।
सामान्य विकल्प eslint-plugin-i18next का no-literal-string rule है। Default रूप से यह file के हर literal के बजाय JSX markup में मौजूद plain text को validate करता है। इसी वजह से यह false positives की दीवार बनने के बजाय वास्तविक codebase में उपयोगी रहता है। इसमें regular expression के जरिए ignore patterns, सुरक्षित माने जाने वाले functions के लिए callee exclusions और markup-only mode का support है।
एक शुरुआती configuration:
// 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*$'],
},
],
},
},
];
इसे केवल editor में नहीं, अपने pipeline में चलाएँ:
npx eslint . --max-warnings=0
अब अदृश्य defect पर red mark दिखाई देता है। Untranslated string के लिए agent को वही feedback loop मिलता है जो type error के लिए पहले से मिलता है। इसका मतलब है कि वह उसी session में अपनी गलती ठीक कर सकता है, बजाय इसके कि किसी दूसरी locale का user उसे खोजे। अगर आप Cursor project में scratch से i18n जोड़ने की पूरी तस्वीर चाहते हैं, तो हमारी 15-minute Cursor and Next.js walkthrough और Cursor integration page देखें।
Failing lint rule पर्याप्त क्यों नहीं है?
क्योंकि red build आपको बताता है कि कोई string मौजूद है। वह उसका अनुवाद नहीं करता।
Rule trigger होने के बाद भी किसी को आपकी मौजूदा namespaces से मेल खाने वाली key चुननी होगी, English source value जोड़नी होगी और बाकी locales तैयार करनी होंगी। दिन में कई बार ship करने वाले solo project में यह काम टलता रहता है। काफी समय तक टलने पर ईमानदार fix की जगह file को ignore list में जोड़ना आसान लगने लगता है—और extra config के साथ आप फिर वहीं पहुँच जाते हैं जहाँ से शुरू किया था।
यही वह gap है जो हल हो चुकी समस्या को recurring debt में बदल देता है। पहली और दूसरी layers समस्या के सामने आने की frequency और उसके पता चलने की speed बदलती हैं। इनमें से कोई भी असली काम नहीं करती।
Three-layer setup कैसा दिखता है?
Instruction, enforcement, automation। हर layer उससे पहले वाली layer से छूट गई चीज़ों को पकड़ती है।
Layer one, instruction। अपने repo root की AGENTS.md में i18n block लिखें और component directories के globs के साथ scoped .cursor/rules/i18n.mdc जोड़ें। लागत: एक बार 15 मिनट। प्रभाव: शुरुआत में ही कम literals लिखे जाएँगे।
Layer two, enforcement। no-literal-string चालू करें और continuous integration को इसके आधार पर fail कराएँ। लागत: मौजूदा codebase में ignore patterns tune करने में एक दोपहर। प्रभाव: कोई literal आपकी main branch तक बिना notice नहीं पहुँचेगा और agent खुद correction कर सकेगा।
Layer three, automation। Extraction, keying और translation को आपके बिना होने दें। यही वह layer है जिसे globalize.now संभालता है। यह आपके i18n runtime के ऊपर बैठता है, उसे replace नहीं करता: next-intl या i18next strings को render करते रहते हैं। globalize.now नया hardcoded text detect करता है, आपके project में पहले से मौजूद namespaces के अनुरूप keys generate करता है, उन्हें configured हर locale में translate करता है और हर Git push पर updated locale files को वापस commit करता है। इसे एक बार setup करें—repository को globalize.now से connect करें—और कोई manual step छूटने का सवाल नहीं। आप इसे अपने agent में इस तरह भी install कर सकते हैं:
npx skills add globalize-now/globalize-skills
Plans €5 प्रति माह से शुरू होते हैं। €20 Starter plan में हर महीने €20 का translation credit शामिल है (लगभग 200,000 words), और included volume से अधिक usage पर उसी per-character rate से billing होती है। न per-seat शुल्क है, न per-language शुल्क। Signup पर बिना card के €5 translation credit मिलता है। Engineers के लिए अधिक जानकारी developers page पर है, और AI tools के साथ ship करने वालों के लिए छोटा version vibe coders page पर।
Three layers का उद्देश्य यही है कि इनमें से कोई भी layer सौ agent sessions में आपकी discipline पर निर्भर न रहे। Rule file rate कम करती है, lint rule failures को स्पष्ट बनाता है और sync fix को free कर देता है। यही combination agent के लगातार rewrite करने के बावजूद multilingual app को multilingual बनाए रखता है।
आपका i18n setup fragile हिस्सा नहीं है। Fragile हिस्सा agent द्वारा string लिखे जाने और उस string के locale file तक पहुँचने के बीच का loop है। globalize.now हर push पर उस loop को पूरा करता है।
globalize.now आपके ऐप्लिकेशन की हार्डकोडेड कॉपी को अनुवाद-तैयार locale फ़ाइलों में बदल देता है और जैसे-जैसे आप नई रिलीज़ करते हैं, उन्हें अपडेट रखता है।
globalize.now को निःशुल्क आजमाएं