← ClaudeAtlas

i18n-rtllisted

Build UI that survives translation and bidirectional text — no concatenated strings, no hardcoded formats, logical CSS properties, and layouts that tolerate 40% longer words. Load when the app is or may become multilingual.
soumit-kaz/lazysitter · ★ 1 · Code & Development · score 72
Install: claude install-skill soumit-kaz/lazysitter
# Internationalization and RTL Retrofitting i18n is one of the most expensive frontend migrations there is. The cheap moves are almost all structural and cost nothing on day one. ## Never build a sentence from parts ```jsx <>{count} {count === 1 ? 'item' : 'items'} in {folderName}</> // untranslatable ``` Word order differs between languages, and plural rules are not binary — Arabic has six forms, Polish three, Japanese one. A concatenated sentence cannot be translated correctly by anyone. Use a full message with named placeholders and proper plural support: ``` "items_in_folder": "{count, plural, one {# item} other {# items}} in {folder}" ``` Every serious i18n library supports ICU message syntax. Use it, including for the "simple" cases — those are the ones that get concatenated. ## Never hardcode a format Dates, times, numbers, currencies, percentages, lists, and relative times are all locale-dependent, and `Intl` handles all of them: ```js new Intl.DateTimeFormat(locale, { dateStyle: 'medium', timeZone: tz }).format(d) new Intl.NumberFormat(locale, { style: 'currency', currency }).format(n) new Intl.RelativeTimeFormat(locale).format(-3, 'day') new Intl.ListFormat(locale).format(['a','b','c']) ``` **Always pass an explicit timezone** for anything server-rendered — the server's timezone and the user's differ, and near midnight they differ by a whole day. That is both a correctness bug and a hydration mismatch. Also: sorting. `Intl.Collator` sorts correctly per lo