i18n-rtllisted
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