i18n issues you may meet
layout issues
- When your users are in
Arabic, the document will be displayed from right to left. So you need to adjust the layout of the document.
html {
direction: rtl;
}
If you use a position absolute property, let element on the left, then when you change the direction of the document, the element still stays on the left. You need to adjust the position of the element to the right.
/* before, direction: ltr */
.element {
position: absolute;
left: 0;
}
/* after, direction: rtl */
.element {
position: absolute;
right: 0;
}
- different language has different character length, so you need to adjust the width and height of the element.
const en = "What's the weather like today?"
const zh = "今天天气怎么样?"
const ar = "ما هو الطقس اليوم ؟"
const ja = "今日の天気はどうですか?"
const ko = "오늘 날씨는 어때요?"
const es = "¿Qué tiempo hace hoy?"
const fr = "Quel temps fait-il aujourd'hui?"
const de = "Wie ist das Wetter heute?"
const it = "Che tempo fa oggi?"
const pt = "Qual a temperatura hoje?"
const nl = "Wat is de weer vandaag?"
const pl = "Jakie jest pogoda dzisiaj?"
const ro = "Ce vreme este azi?"
const tr = "Bugün hava nasıl?"
const vi = "Hôm nay thời tiết thế nào?"
- different countries have different price format
For example, in Brazil (pt-BR), prices use commas as decimal separators instead of periods/points:
// US/UK format
$10.50 (using decimal point)
// Brazil format
R$ 10,50 (using comma as decimal separator)
plural rules
Different languages have different plural rules. For example:
- English has two forms: singular (1 minute) and plural (2 minutes)
- Chinese has only one form: 1 分钟, 2 分钟
- Russian has three forms: 1 минута, 2 минуты, 5 минут
- Arabic has six forms: 0 دقيقة, 1 دقيقة, 2 دقيقة, 3-10 دقائق, 11-99 دقيقة, 100+ دقيقة
You can use libraries like i18next to handle plural rules:
// English
i18next.t("key", { count: 1 }) // "1 minute"
i18next.t("key", { count: 2 }) // "2 minutes"
// Chinese
i18next.t("key", { count: 1 }) // "1分钟"
i18next.t("key", { count: 2 }) // "2分钟"
// Russian
i18next.t("key", { count: 1 }) // "1 минута"
i18next.t("key", { count: 2 }) // "2 минуты"
i18next.t("key", { count: 5 }) // "5 минут"
The key in i18next is a unique identifier for your translation strings. It's like a variable name that maps to different translations in different languages. Here's how it works:
// translation files
// en.json
{
"time.minutes": {
"one": "{{count}} minute",
"other": "{{count}} minutes"
}
}
// zh.json
{
"time.minutes": "{{count}}分钟"
}
// Usage
i18next.t('time.minutes', { count: 1 }); // "1 minute" in English, "1分钟" in Chinese
i18next.t('time.minutes', { count: 2 }); // "2 minutes" in English, "2分钟" in Chinese
The key can be:
- A simple string:
"welcome" - A nested path:
"common.buttons.submit" - A key with plural forms:
"time.minutes"
The plural forms like one and other are special keys that i18next uses to handle different plural rules:
one: Used for singular form (when count is 1)other: Used for plural form (when count is 0 or > 1)
Some languages have more plural forms. For example, in Russian:
// ru.json
{
"time.minutes": {
"one": "{{count}} минута", // 1
"few": "{{count}} минуты", // 2-4
"many": "{{count}} минут", // 5-20
"other": "{{count}} минуты" // 21, 22, 25-30, etc.
}
}
The plural rules are based on the CLDR (Common Locale Data Repository) specification, which defines plural rules for different languages. i18next automatically selects the correct form based on the count and the current language's rules.
If your translation files don't support nested structure, you have a simple solution:
minute > 1 ? t("{num} minutes) : t("{num} minute)
But this approach has several problems:
- It doesn't work for languages with more than two plural forms (like Russian, Arabic, etc.)
- It doesn't handle zero correctly in many languages
- It's not maintainable - you need to write this logic everywhere you need plural forms
- It doesn't follow the CLDR standards, which means your translations might be incorrect
- It makes it harder for translators to work with your translation files
For example, in Russian:
// Wrong approach
minute > 1 ? t("{num} минут") : t("{num} минута")
// This would be wrong for:
// 2-4 minutes (should be "минуты")
// 5-20 minutes (should be "минут")
// 21, 22, 25-30 minutes (should be "минуты")
That's why it's better to use i18next's built-in plural handling:
policy issues
- Don't show strikethrough price in Turkey for legal reasons
Due to the Turkish government's regulations, we cannot display the strikethrough price on the product page. For example, if you have a product with a original price of 100 TL and a discounted price of 80 TL, you cannot display it as 100 TL → 80 TL. You need to display it as 80 TL.
<!-- this is not allowed in Turkey -->
<span class="current-price">80</span>
<del>
<span class="original-price">100</span>
<span class="currency">₺</span>
</del>