ICU MessageFormat एक Unicode standard है, जिसका उपयोग ऐसी एक translatable string लिखने के लिए होता है जो count, gender और अन्य variables के अनुसार बदल सके। इसका अनुवाद अब भी कठिन है, क्योंकि syntax code के लिए बनाया गया था, localization करने वाले लोगों के लिए नहीं। यह spec एक दशक से भी अधिक समय से मौजूद है, और nested curly braces को देखकर सबसे अधिक परेशानी non-technical translators को होती है। globalize.now AI-powered localization infrastructure है, जो इस समस्या से एक layer नीचे काम करता है: यह strings extract करके वे locale files बनाता है जहाँ ये ICU patterns रहते हैं, और फिर हर Git push पर उन्हें sync में रखता है।
ICU MessageFormat क्या है?
ICU MessageFormat ऐसी message लिखने का syntax है जिसकी अंतिम wording runtime data पर निर्भर करती है। Code में fragments जोड़ने के बजाय आप एक pattern लिखते हैं और formatter को locale के अनुसार सही branch चुनने देते हैं।
इसका सबसे आम उपयोग pluralization है:
{count, plural,
one {You have # message}
other {You have # messages}
}
# की जगह number आ जाता है, और one / other branches किसी language की plural categories से map होती हैं। English में दो categories हैं; Polish, Russian और Arabic में अधिक। ICU gender और अन्य choices को भी select के ज़रिए संभालता है:
{gender, select,
male {He liked your post}
female {She liked your post}
other {They liked your post}
}
इसी वजह से ICU de facto pluralization standard बना: यह grammatical complexity को ऐसे data में रखता है जो हर language के अनुसार बदल सकता है, बजाय इसके कि उसे ऐसी branching logic में रखा जाए जो केवल उसी language में काम करे जिसमें लिखी गई है। FormatJS, i18next और next-intl जैसी runtime libraries इसे समझती हैं।
ICU MessageFormat का अनुवाद करना इतना कठिन क्यों है?
इसका अनुवाद कठिन है क्योंकि syntax developers के लिए बनाया गया था, जबकि strings का वास्तविक अनुवाद करने वाले लोग आम तौर पर developers नहीं होते।
Locale file खोलने वाले translator को “You have 3 messages.” दिखाई नहीं देता। उसे curly braces, plural और select जैसे keywords, ऐसी plural categories जिन्हें वह शायद पहचानता भी न हो, और # placeholder दिखाई देता है जो typo जैसा लगता है। एक bracket हट जाए या category का नाम बदल जाए, तो string render होने के बजाय runtime पर error दे देती है। ICU को engineers के लिए शक्तिशाली बनाने वाली structure ही linguist के हाथों में उसे fragile बनाती है।
यह वही gap है जिसके साथ localization industry वर्षों से चुपचाप काम करती आई है। अधिकांश tools raw pattern दिखाकर उम्मीद करते हैं कि translator गलत character नहीं छुएगा, या plural forms को अलग editor के पीछे छिपा देते हैं—जिसमें भी translator को plural categories समझनी पड़ती हैं। Spec की complexity और non-technical translator के mental model के बीच की दूरी को किसी vendor ने पूरी तरह खत्म नहीं किया है।
MessageFormat 2.0 में क्या बदला?
MessageFormat 2.0 syntax का ground-up redesign है, और 2025 में यह draft के बजाय stable standard बन गया।
MF2 मार्च 2025 में Final Candidate status तक पहुँचा और अब CLDR का stable हिस्सा है। इसे Unicode LDML technical standard के भाग के रूप में प्रकाशित किया गया है और LDML 47 तथा 48 releases के ज़रिए refine किया गया है। Reference implementation 2026 की शुरुआत में जारी LDML 48.2 version के अनुसार spec को track करता है। नया syntax inputs को match logic से अलग करता है और named formatting functions को support करता है, जिससे complex messages अधिक readable बनती हैं:
.input {$count :number}
.match $count
one {{You have {$count} message}}
* {{You have {$count} messages}}
उद्देश्य ऐसा pattern बनाना है जिसे extend करना आसान हो और जो मूल nested braces की तुलना में पढ़ने में थोड़ा कम कठिन लगे।
क्या MessageFormat 2.0 translator की समस्या हल करता है?
अभी नहीं—दो कारणों से।
पहला, MF2 syntax की ergonomics बेहतर करता है, लेकिन यह अब भी syntax ही है। Translator को अभी भी .match, plural keys और braces दिखाई देंगे। MF1 की तुलना में cognitive load कम है, लेकिन खत्म नहीं हुआ; गलत token edit करके non-technical translator अब भी message तोड़ सकता है।
दूसरा, production में इसे लगभग कोई नहीं चला रहा। 2026 में भी adoption सीमित है: JavaScript side के लिए TC39 process में आगे बढ़ने से पहले लगभग एक दर्जन organizations का MF2 को production में इस्तेमाल करना अपेक्षित है, और यह threshold अभी पूरा नहीं हुआ है। व्यवहार में आज ship किए जाने वाले अधिकांश apps अब भी FormatJS और i18next जैसी libraries के ज़रिए मूल ICU MessageFormat पर चलते हैं। इसलिए translator-facing समस्या किसी spec से हल नहीं होती; यह इस बात से हल होती है कि syntax कहाँ produce और maintain किया जाता है।
AI-generated apps में ICU MessageFormat कहाँ टूटता है?
यह शुरुआत में ही टूट जाता है, क्योंकि AI coding tools पहली कोशिश में सही ICU बहुत कम generate करते हैं।
जब आप Cursor, Claude Code या Lovable के साथ build करते हैं, तो generated code counts को आम तौर पर naive तरीके से संभालता है:
// What an AI coding tool often generates
const label = count + " " + (count === 1 ? "message" : "messages");
यह logic English के लिए सही और अधिकांश अन्य languages के लिए गलत है, क्योंकि यह ठीक दो plural forms मानकर चलता है। यह sentence को application code में भी embed कर देता है, इसलिए translator के localize करने के लिए locale file में कोई ICU pattern बचता ही नहीं। Localization layer के लिए string तब तक अदृश्य रहती है जब तक production में टूटी हुई grammar दिखाई न दे। AI tools keys को duplicate भी करते हैं और hardcoded text को components में बिखेरते हैं, इसलिए ICU अपनाने की इच्छा रखने वाली teams के पास भी ऐसी strings रह जाती हैं जो कभी translatable file तक पहुँची ही नहीं। globalize.now developer overview ठीक इसी तरह की strings को ship होने से पहले पकड़ने के लिए बनाया गया है।
2026 में developers को ICU MessageFormat को कैसे संभालना चाहिए?
ICU को हाथ से लिखी content नहीं, बल्कि generated infrastructure मानें।
व्यावहारिक नियम यह है: डेवलपर्स और AI टूल्स को कोड में plural concatenation नहीं लिखना चाहिए, और अनुवादकों को raw ICU braces को हाथ से संपादित नहीं करना चाहिए। ICU pattern उस locale file में होना चाहिए जिसे अपने-आप बनाया और अपडेट रखा जाए, फिर FormatJS, i18next या next-intl जैसी लाइब्रेरी उसे runtime पर render करे। इससे syntax बनते समय ही सही रहता है और ऐप में बदलाव होने पर हर locale में एकसमान बना रहता है। यदि आप यह तय कर रहे हैं कि आपके runtime layer के साथ ICU की भूमिका कहाँ आती है, तो globalize.now vs i18next comparison में बताया गया है कि infrastructure और runtime के बीच काम कैसे बाँटा जाता है।
globalize.now इसी layer पर काम करता है। यह आपके codebase से hardcoded strings निकालता है, वे keys और locale files बनाता है जिनमें ICU patterns रहते हैं, और हर Git push पर उन्हें फिर से sync करता है, ताकि structure बिना किसी manual export step के सही बना रहे। यह translator के editor बनने या आपकी runtime library को replace करने की कोशिश नहीं करता; यह सुनिश्चित करता है कि उन tools पर निर्भर ICU-आधारित files वास्तव में मौजूद हों और sync में बनी रहें। vibe-coders guide में Lovable, Bolt और Replit से बने apps के लिए यही setup समझाया गया है, और व्यापक workflow globalize.now homepage पर उपलब्ध है।
globalize.now आपके ऐप्लिकेशन की हार्डकोडेड कॉपी को अनुवाद-तैयार locale फ़ाइलों में बदल देता है और जैसे-जैसे आप नई रिलीज़ करते हैं, उन्हें अपडेट रखता है।
globalize.now को निःशुल्क आजमाएं