Build and maintain internationalized interfaces that feel native in every supported locale, not merely translated.
Localization is more than swapping strings. It is adapting layout, formatting, content, and interaction patterns so that users in every market experience the product as intentional, not as an afterthought.
Consult the language and locale selection reference when designing language selectors, country pickers, currency choosers, or regional-preference controls.
Consult the component accessibility reference when localizing custom components that must remain keyboard-navigable and screen-reader friendly across locales.
Consult the error-recovery reference when localizing validation messages, error states, and recovery flows.
Consult the date-input-ux and date-time-picker-ux references when adapting date, time, and calendar patterns to locale conventions.
MANDATORY PREPARATION
Users start this workflow with /localize. Once this skill is active, load $frontend-design — it contains design principles, anti-patterns, and the Context Gathering Protocol. Follow that protocol before proceeding — if no design context exists yet, you MUST load $setup first. Additionally gather: which markets and languages are targeted now and next, whether the product is content-heavy or UI-heavy, and whether translation will be done in-house, by agency, or through a TMS.
Assess Localization Scope
Understand what must change and how deep the adaptation goes:
Content surface area:
- Static UI strings (labels, buttons, headings, empty states)
- Dynamic user-generated content (names, descriptions, comments)
- Marketing and legal copy (terms, privacy, compliance)
- Error messages and validation feedback
- Notifications, emails, and off-product messaging
Formatting and conventions:
- Date, time, and calendar formats (ISO vs localized display)
- Number formats (decimal separators, grouping, currency)
- Measurement units (metric vs imperial, currency symbols)
- Address and phone number formats
- Name ordering (given name first vs family name first)
- Sorting and collation rules
Layout and structural adaptation:
- Text expansion and contraction (German +30%, Japanese -10%)
- Right-to-left (RTL) script requirements
- Vertical text or mixed-script layouts
- Reading direction and scanning patterns
Content and legal differences:
- Region-specific features or catalog availability
- Legal requirements (GDPR, CCPA, local tax, age gates)
- Payment methods and currency support
- Cultural imagery, colors, and symbolism
Localization Architecture
String Management Strategy
Key-based extraction:
- Use descriptive, hierarchical keys:
checkout.shipping.title, errors.email.required
- Avoid English sentences as keys; they break when source copy changes
- Include context comments for translators:
// Used as button label on shipping form
- Namespace by feature or route to keep files manageable
Message format:
- Use ICU MessageFormat for interpolation, pluralization, and gender
- Avoid concatenating strings in code; translators need full sentences
// Good: complete sentence with interpolation
{count, plural, =0 {No items} one {# item} other {# items}} in your cart
// Bad: concatenated fragments
t('items_prefix') + count + t('items_suffix')
Source language discipline:
- Treat the source language (usually English) as the development contract
- Write source strings for translation: complete sentences, clear pronoun references, no idioms
- Review source copy for translatability before sending to translators
Locale Negotiation and Routing
URL strategy (choose one and commit):
- Subdirectories:
/en/products, /de/products — SEO-friendly, shareable, clear
- Subdomains:
en.example.com, de.example.com — clean separation, harder to maintain
- Query parameters:
?lang=de — simplest to implement, worst for SEO and sharing
Locale detection order:
- Explicit user preference (stored in account or cookie)
- URL path or subdomain
- Browser
Accept-Language header
- Geolocation (use as soft default only, never hard redirect)
Locale persistence:
- Store explicit choices in user profiles when authenticated
- Use cookies for anonymous visitors; respect them on return
- Never override an explicit choice with auto-detection
Library and Tool Selection
| Need |
Strong options |
When to use |
| React / modern frameworks |
react-i18next, Lingui, FormatJS (react-intl) |
Component-level translations with hooks/context |
| Vue |
vue-i18n |
Vue 2/3 with composition or options API |
| Svelte |
svelte-i18n, typesafe-i18n |
Lightweight, store-based reactivity |
| Vanilla JS / framework-agnostic |
i18next, FormatJS IntlMessageFormat |
Shared across stacks, extensive plugin ecosystem |
| Build-time extraction |
Lingui, typesafe-i18n |
Smaller bundles, no runtime parsing |
| Runtime extraction |
i18next, react-i18next |
Dynamic loading, CMS-driven content |
| Translation management |
Phrase, Lokalise, Crowdin, Smartling |
Team collaboration, TMS workflows, in-context editing |
Pragmatic rules:
- Prefer one i18n library per project. Multiple libraries fragment key conventions and loading behavior.
- If the project is small and static, build-time extraction with JSON/PO files is enough.
- If translations change frequently or non-developers edit them, integrate a TMS early.
Implementation Dimensions
Text Expansion and Layout Resilience
Space budget:
- Add 30-40% horizontal space for German, Finnish, and other expansion-heavy languages
- Test shortest languages (Chinese, Japanese) for excessive whitespace or broken visual rhythm
- Use min/max widths, not fixed widths, on buttons, labels, and navigation items
Container behavior:
- Favor flexbox and grid that adapt to content length
- Allow text wrapping; do not force single-line layouts on labels
- Test truncation behavior when expansion exceeds available space
RTL and Bidirectional Text
CSS logical properties:
/* Use logical properties for margins, padding, borders */
margin-inline-start: 1rem;
padding-inline: 1rem;
border-inline-end: 1px solid;
Direction-aware transforms:
[dir="rtl"] .arrow { transform: scaleX(-1); }
[dir="rtl"] .timeline { flex-direction: row-reverse; }
Mirroring considerations:
- Mirror navigation, breadcrumbs, and back buttons
- Do not mirror icons that represent physical objects (clocks, text cursors)
- Do mirror directional icons (arrows, chevrons, progress indicators)
- Test with native RTL speakers; mechanical mirroring often misses cultural patterns
Formatting and Data Display
Dates and times:
- Use
Intl.DateTimeFormat or library equivalents; never hardcode format strings
- Respect 12-hour vs 24-hour conventions per locale
- Consider calendar systems (Gregorian, Buddhist, Islamic) where relevant
Numbers and currency:
- Use
Intl.NumberFormat for grouping, decimals, and currency symbols
- Currency symbols can prefix or suffix depending on locale (
$1,234.56 vs 1.234,56 €)
- Display currency codes (USD, EUR) alongside symbols for clarity in multi-currency contexts
Pluralization, ordinals, and grammar:
- Use ICU MessageFormat plural rules; do not assume English
one/other
- Arabic has six plural forms; Polish has four; Welsh has six
- Handle gendered grammar and ordinals (1st, 2nd, 3rd) through message format, not code logic
Content Beyond Strings
Images and media:
- Replace text-in-images with live text whenever possible
- Maintain locale-specific image sets when visuals contain culturally specific content
- Use SVG for icons and diagrams; they scale and mirror more cleanly
URLs and SEO:
- Use
hreflang annotations to indicate language/region variants
- Include locale in canonical URLs
- Localize meta titles and descriptions, not just page content
- Avoid locale-inappropriate keywords in URL slugs
Legal and compliance content:
- Maintain region-specific legal copy (terms, privacy, cookie notices)
- Do not auto-translate legal text; use certified legal translators
- Keep compliance content versioned per jurisdiction
Translation Workflow
Developer handoff:
- Extract strings from code into translation files (JSON, PO, YAML)
- Add context comments and screenshot references for ambiguous strings
- Freeze source strings before sending to translation to prevent mid-translation churn
- Version translation files alongside code releases
Quality assurance:
- Review translations for truncation, overflow, and broken layout
- Verify that placeholders and HTML tags are preserved
- Check that gendered translations match the intended context
- Run pseudo-localization (accented expansion) before real translation to catch layout bugs early
Continuous localization:
- Integrate TMS with version control (GitHub/GitLab webhooks)
- Automate extraction on pull requests
- Set up translation memory to reduce cost and improve consistency
- Notify translators of new or changed keys promptly
Testing Localized UI
Layout testing:
- Test with longest and shortest supported languages
- Verify RTL layouts with native browser direction switching
- Check truncation, wrapping, and overflow at minimum and maximum viewport widths
Functional testing:
- Validate that interpolation variables populate correctly in all locales
- Confirm pluralization rules render correctly (0, 1, 2, 5, 11, 21 items)
- Test locale switching without full page reload where applicable
- Verify that persisted locale preferences survive logout and re-login
Content testing:
- Spot-check translations for accuracy and tone consistency
- Verify that legal and compliance copy matches the certified version
- Ensure that localized URLs and SEO metadata are present
Anti-Patterns
- Concatenate translated fragments: Translators need complete sentences.
t('you_have') + count + t('messages') breaks in most languages.
- Hardcode locale assumptions: Do not assume left-to-right, 12-hour time, MM/DD/YYYY, or English plural rules.
- Auto-translate UI without review: Machine translation for UI strings produces inconsistent terminology and broken grammar.
- Ignore text expansion: Fixed-width buttons and labels break in German and other expansion-heavy languages.
- Use flags for languages: A flag represents a country, not a language. Spanish has 20+ countries; English has dozens. Use language names or neutral icons.
- Redirect based on IP alone: Travelers, VPN users, and expats get trapped in wrong locales. Suggest, do not force.
- Skip pseudo-localization: Running pseudo-locale tests before real translation catches layout and truncation bugs when they are still cheap to fix.
- Store translations in version control without versioning: Translation files should be tagged and released alongside code so rollback is possible.
- Forget to localize error messages: Untranslated validation errors are a frequent source of user confusion and abandonment.
- Treat localization as a one-time project: Languages evolve, products add features, and markets change. Localization is continuous maintenance.
Verify Localization Readiness
Before shipping a localized product:
1---
2name: localize
3description: Plan, implement, or improve an internationalization and localization strategy for UI content, formatting, and regional adaptation. Use when the user asks to add i18n, localize, translate, support multiple languages, handle regional formats, manage locale switching, or build a multilingual product.
4metadata:
5 argument-hint: "[target]"
6---
7
8Build and maintain internationalized interfaces that feel native in every supported locale, not merely translated.
9
10Localization is more than swapping strings. It is adapting layout, formatting, content, and interaction patterns so that users in every market experience the product as intentional, not as an afterthought.
11
12Consult the [language and locale selection](../frontend-design/reference/language-and-locale-selection.md) reference when designing language selectors, country pickers, currency choosers, or regional-preference controls.
13Consult the [component accessibility](../frontend-design/reference/component-accessibility.md) reference when localizing custom components that must remain keyboard-navigable and screen-reader friendly across locales.
14Consult the [error-recovery](../frontend-design/reference/error-recovery.md) reference when localizing validation messages, error states, and recovery flows.
15Consult the [date-input-ux](../frontend-design/reference/date-input-ux.md) and [date-time-picker-ux](../frontend-design/reference/date-time-picker-ux.md) references when adapting date, time, and calendar patterns to locale conventions.
16
17## MANDATORY PREPARATION
18
19Users start this workflow with `/localize`. Once this skill is active, load $frontend-design — it contains design principles, anti-patterns, and the **Context Gathering Protocol**. Follow that protocol before proceeding — if no design context exists yet, you MUST load $setup first. Additionally gather: which markets and languages are targeted now and next, whether the product is content-heavy or UI-heavy, and whether translation will be done in-house, by agency, or through a TMS.
20
21## Assess Localization Scope
22
23Understand what must change and how deep the adaptation goes:
24
251. **Content surface area**:
26 - Static UI strings (labels, buttons, headings, empty states)
27 - Dynamic user-generated content (names, descriptions, comments)
28 - Marketing and legal copy (terms, privacy, compliance)
29 - Error messages and validation feedback
30 - Notifications, emails, and off-product messaging
31
322. **Formatting and conventions**:
33 - Date, time, and calendar formats (ISO vs localized display)
34 - Number formats (decimal separators, grouping, currency)
35 - Measurement units (metric vs imperial, currency symbols)
36 - Address and phone number formats
37 - Name ordering (given name first vs family name first)
38 - Sorting and collation rules
39
403. **Layout and structural adaptation**:
41 - Text expansion and contraction (German +30%, Japanese -10%)
42 - Right-to-left (RTL) script requirements
43 - Vertical text or mixed-script layouts
44 - Reading direction and scanning patterns
45
464. **Content and legal differences**:
47 - Region-specific features or catalog availability
48 - Legal requirements (GDPR, CCPA, local tax, age gates)
49 - Payment methods and currency support
50 - Cultural imagery, colors, and symbolism
51
52## Localization Architecture
53
54### String Management Strategy
55
56**Key-based extraction**:
57- Use descriptive, hierarchical keys: `checkout.shipping.title`, `errors.email.required`
58- Avoid English sentences as keys; they break when source copy changes
59- Include context comments for translators: `// Used as button label on shipping form`
60- Namespace by feature or route to keep files manageable
61
62**Message format**:
63- Use ICU MessageFormat for interpolation, pluralization, and gender
64- Avoid concatenating strings in code; translators need full sentences
65
66```icu
67// Good: complete sentence with interpolation
68{count, plural, =0 {No items} one {# item} other {# items}} in your cart
69
70// Bad: concatenated fragments
71t('items_prefix') + count + t('items_suffix')
72```
73
74**Source language discipline**:
75- Treat the source language (usually English) as the development contract
76- Write source strings for translation: complete sentences, clear pronoun references, no idioms
77- Review source copy for translatability before sending to translators
78
79### Locale Negotiation and Routing
80
81**URL strategy** (choose one and commit):
82- **Subdirectories**: `/en/products`, `/de/products` — SEO-friendly, shareable, clear
83- **Subdomains**: `en.example.com`, `de.example.com` — clean separation, harder to maintain
84- **Query parameters**: `?lang=de` — simplest to implement, worst for SEO and sharing
85
86**Locale detection order**:
871. Explicit user preference (stored in account or cookie)
882. URL path or subdomain
893. Browser `Accept-Language` header
904. Geolocation (use as soft default only, never hard redirect)
91
92**Locale persistence**:
93- Store explicit choices in user profiles when authenticated
94- Use cookies for anonymous visitors; respect them on return
95- Never override an explicit choice with auto-detection
96
97### Library and Tool Selection
98
99| Need | Strong options | When to use |
100|------|----------------|-------------|
101| React / modern frameworks | react-i18next, Lingui, FormatJS (react-intl) | Component-level translations with hooks/context |
102| Vue | vue-i18n | Vue 2/3 with composition or options API |
103| Svelte | svelte-i18n, typesafe-i18n | Lightweight, store-based reactivity |
104| Vanilla JS / framework-agnostic | i18next, FormatJS IntlMessageFormat | Shared across stacks, extensive plugin ecosystem |
105| Build-time extraction | Lingui, typesafe-i18n | Smaller bundles, no runtime parsing |
106| Runtime extraction | i18next, react-i18next | Dynamic loading, CMS-driven content |
107| Translation management | Phrase, Lokalise, Crowdin, Smartling | Team collaboration, TMS workflows, in-context editing |
108
109**Pragmatic rules**:
110- Prefer one i18n library per project. Multiple libraries fragment key conventions and loading behavior.
111- If the project is small and static, build-time extraction with JSON/PO files is enough.
112- If translations change frequently or non-developers edit them, integrate a TMS early.
113
114## Implementation Dimensions
115
116### Text Expansion and Layout Resilience
117
118**Space budget**:
119- Add 30-40% horizontal space for German, Finnish, and other expansion-heavy languages
120- Test shortest languages (Chinese, Japanese) for excessive whitespace or broken visual rhythm
121- Use min/max widths, not fixed widths, on buttons, labels, and navigation items
122
123**Container behavior**:
124- Favor flexbox and grid that adapt to content length
125- Allow text wrapping; do not force single-line layouts on labels
126- Test truncation behavior when expansion exceeds available space
127
128### RTL and Bidirectional Text
129
130**CSS logical properties**:
131```css
132/* Use logical properties for margins, padding, borders */
133margin-inline-start: 1rem;
134padding-inline: 1rem;
135border-inline-end: 1px solid;
136```
137
138**Direction-aware transforms**:
139```css
140[dir="rtl"] .arrow { transform: scaleX(-1); }
141[dir="rtl"] .timeline { flex-direction: row-reverse; }
142```
143
144**Mirroring considerations**:
145- Mirror navigation, breadcrumbs, and back buttons
146- Do not mirror icons that represent physical objects (clocks, text cursors)
147- Do mirror directional icons (arrows, chevrons, progress indicators)
148- Test with native RTL speakers; mechanical mirroring often misses cultural patterns
149
150### Formatting and Data Display
151
152**Dates and times**:
153- Use `Intl.DateTimeFormat` or library equivalents; never hardcode format strings
154- Respect 12-hour vs 24-hour conventions per locale
155- Consider calendar systems (Gregorian, Buddhist, Islamic) where relevant
156
157**Numbers and currency**:
158- Use `Intl.NumberFormat` for grouping, decimals, and currency symbols
159- Currency symbols can prefix or suffix depending on locale (`$1,234.56` vs `1.234,56 €`)
160- Display currency codes (USD, EUR) alongside symbols for clarity in multi-currency contexts
161
162**Pluralization, ordinals, and grammar**:
163- Use ICU MessageFormat plural rules; do not assume English `one/other`
164- Arabic has six plural forms; Polish has four; Welsh has six
165- Handle gendered grammar and ordinals (1st, 2nd, 3rd) through message format, not code logic
166
167### Content Beyond Strings
168
169**Images and media**:
170- Replace text-in-images with live text whenever possible
171- Maintain locale-specific image sets when visuals contain culturally specific content
172- Use SVG for icons and diagrams; they scale and mirror more cleanly
173
174**URLs and SEO**:
175- Use `hreflang` annotations to indicate language/region variants
176- Include locale in canonical URLs
177- Localize meta titles and descriptions, not just page content
178- Avoid locale-inappropriate keywords in URL slugs
179
180**Legal and compliance content**:
181- Maintain region-specific legal copy (terms, privacy, cookie notices)
182- Do not auto-translate legal text; use certified legal translators
183- Keep compliance content versioned per jurisdiction
184
185## Translation Workflow
186
187**Developer handoff**:
1881. Extract strings from code into translation files (JSON, PO, YAML)
1892. Add context comments and screenshot references for ambiguous strings
1903. Freeze source strings before sending to translation to prevent mid-translation churn
1914. Version translation files alongside code releases
192
193**Quality assurance**:
194- Review translations for truncation, overflow, and broken layout
195- Verify that placeholders and HTML tags are preserved
196- Check that gendered translations match the intended context
197- Run pseudo-localization (accented expansion) before real translation to catch layout bugs early
198
199**Continuous localization**:
200- Integrate TMS with version control (GitHub/GitLab webhooks)
201- Automate extraction on pull requests
202- Set up translation memory to reduce cost and improve consistency
203- Notify translators of new or changed keys promptly
204
205## Testing Localized UI
206
207**Layout testing**:
208- Test with longest and shortest supported languages
209- Verify RTL layouts with native browser direction switching
210- Check truncation, wrapping, and overflow at minimum and maximum viewport widths
211
212**Functional testing**:
213- Validate that interpolation variables populate correctly in all locales
214- Confirm pluralization rules render correctly (0, 1, 2, 5, 11, 21 items)
215- Test locale switching without full page reload where applicable
216- Verify that persisted locale preferences survive logout and re-login
217
218**Content testing**:
219- Spot-check translations for accuracy and tone consistency
220- Verify that legal and compliance copy matches the certified version
221- Ensure that localized URLs and SEO metadata are present
222
223## Anti-Patterns
224
225- **Concatenate translated fragments**: Translators need complete sentences. `t('you_have') + count + t('messages')` breaks in most languages.
226- **Hardcode locale assumptions**: Do not assume left-to-right, 12-hour time, MM/DD/YYYY, or English plural rules.
227- **Auto-translate UI without review**: Machine translation for UI strings produces inconsistent terminology and broken grammar.
228- **Ignore text expansion**: Fixed-width buttons and labels break in German and other expansion-heavy languages.
229- **Use flags for languages**: A flag represents a country, not a language. Spanish has 20+ countries; English has dozens. Use language names or neutral icons.
230- **Redirect based on IP alone**: Travelers, VPN users, and expats get trapped in wrong locales. Suggest, do not force.
231- **Skip pseudo-localization**: Running pseudo-locale tests before real translation catches layout and truncation bugs when they are still cheap to fix.
232- **Store translations in version control without versioning**: Translation files should be tagged and released alongside code so rollback is possible.
233- **Forget to localize error messages**: Untranslated validation errors are a frequent source of user confusion and abandonment.
234- **Treat localization as a one-time project**: Languages evolve, products add features, and markets change. Localization is continuous maintenance.
235
236## Verify Localization Readiness
237
238Before shipping a localized product:
239
240- [ ] All user-facing strings are extracted and keyed, not hardcoded
241- [ ] Source copy is reviewed for translatability (complete sentences, no idioms)
242- [ ] Layouts are tested with longest and shortest target languages
243- [ ] RTL scripts are supported with logical properties and directional testing
244- [ ] Date, number, and currency formatting use locale-aware APIs
245- [ ] Pluralization handles all target language plural forms correctly
246- [ ] Locale switching preserves user context and state
247- [ ] URLs include locale and use `hreflang` annotations
248- [ ] Legal and compliance copy is region-specific and certified
249- [ ] Translation workflow is documented and integrated with release cadence
250- [ ] Pseudo-localization passes layout and truncation checks before real translation begins