SEO

Design System Localization: Adapting Components for Every Language

Eray Gündoğmuş
Eray Gündoğmuş
·12 min read
Share
Design System Localization: Adapting Components for Every Language

Design System Localization: Adapting Components for Every Language

Design systems are the foundation of consistent, scalable UI development. But a design system that hasn't accounted for internationalization will break in predictable and painful ways when your product goes global.

Text expands. Layouts need to flip. Scripts change direction. Character sets require different font configurations. Date pickers assume Western calendars. Color palettes carry cultural meaning. A truly global design system must encode the answers to all of these problems into its components from the start.

This guide covers how to build localization into your design system—whether you're starting fresh or retrofitting an existing system.

The Core Problem: Design Systems Are Often Built for One Language

Most design systems are built with a single language in mind—usually English—and then struggle when localization requirements emerge. The symptoms are familiar:

  • Text overflows button boundaries in German
  • Arabic text appears left-aligned instead of right-aligned
  • Date pickers show Sunday as the first day of the week for users in cultures where Monday is the first day
  • Icons with directional meaning (back arrows, progress indicators) are not mirrored for RTL
  • Currency symbols appear in the wrong position
  • Line heights are too tight for languages with ascenders and descenders like Thai or Devanagari

These aren't edge cases—they're predictable failures that emerge every time an English-centric design system encounters a new language.

Text Expansion: Designing for Language Flexibility

English is one of the more compact written languages. When UI copy is translated, it almost always expands:

LanguageTypical expansion from English
German+30-40%
French+20-30%
Spanish+20-30%
Brazilian Portuguese+25-35%
Finnish+30-50%
Russian+15-20%
Japanese-10-20% (contracts)
Chinese-20-30% (contracts)
Arabic±15% (varies significantly)

Design System Patterns for Text Expansion

Avoid fixed-width containers for text: Instead of width: 120px, use min-width: 120px or max-content widths with appropriate overflow handling.

Test with the longest likely translation: Build a habit of testing components with German or Finnish strings. If your button says "Subscribe to Newsletter", your German translator may need to render "Newsletter abonnieren" which is slightly longer but manageable—or a fully spelled out version that's much longer.

Use flexible layouts: CSS flexbox and grid handle text expansion gracefully when configured correctly. Avoid pixel-based spacers between text elements.

Provide character limit guidance in your design tokens: Document maximum recommended string lengths for each component type. Give translators this information upfront. See translation context for how this metadata improves translation quality.

Truncation as a last resort: When text must be truncated, provide a tooltip with the full text (which must also be translatable) and ensure the truncation logic is language-aware (no mid-character truncation in CJK).

RTL Support: Mirroring More Than Text Direction

Right-to-left (RTL) language support is one of the most comprehensive transformations a design system must support. It's not just about text direction—it's about spatial reasoning in a mirrored world.

What Flips in RTL

Layout: The entire page layout mirrors. Left column becomes right column. Navigation drawers that open from the left open from the right.

Text alignment: Default text alignment becomes right-aligned. Left-aligned text in LTR becomes right-aligned in RTL.

Directional icons: Icons that carry directional meaning must be mirrored:

  • Back arrow (←) in LTR becomes forward arrow direction (→ visual position) in RTL
  • Checkmark (progress from left to right) mirrors
  • List icons (bullet points, numbered lists) shift sides

Icons that do NOT flip: Abstract icons, logos, and icons without directional meaning should not flip:

  • Warning triangle: same in both directions
  • Heart, star, circular icons: same in both directions
  • Logos: never mirror

Form fields: Input text alignment, placeholder position, and icon positions within inputs flip.

Padding and margins: padding-left becomes padding-right and vice versa.

Using CSS Logical Properties

The modern solution is CSS logical properties, which automatically adapt to writing direction:

/* Old approach: hardcoded directions */
.card {
  padding-left: 16px;
  padding-right: 24px;
  margin-left: auto;
  border-left: 2px solid blue;
  text-align: left;
}

/* Modern approach: logical properties */
.card {
  padding-inline-start: 16px;
  padding-inline-end: 24px;
  margin-inline-start: auto;
  border-inline-start: 2px solid blue;
  text-align: start;
}

With logical properties and dir="rtl" on the <html> element, your layout automatically mirrors.

For a complete guide, see RTL support in CSS and React.

RTL in Your Design Tokens

Define directional tokens using logical property names:

{
  "spacing": {
    "inline-start": { "value": "16px" },
    "inline-end": { "value": "24px" }
  }
}

And ensure your design tool exports logical properties, not directional ones (Figma's recent updates have improved this, but verify your export pipeline).

Typography: Multi-Script Font Systems

A design system must specify fonts that work across all scripts your product supports.

Font Stacks for Multi-Script Support

A font that works for Latin text may lack glyphs for Cyrillic, Arabic, CJK, Devanagari, or Thai scripts. Build your font stack to cascade appropriately:

/* Comprehensive multi-script font stack */
font-family: 
  'Your Brand Font',          /* Latin, primary brand */
  'Noto Sans',                 /* Universal script coverage */
  -apple-system,              /* Apple system fonts (good CJK on macOS/iOS) */
  BlinkMacSystemFont,         /* Chrome on macOS */
  'Hiragino Kaku Gothic ProN', /* Japanese */
  'Hiragino Sans',            /* Japanese */
  'Meiryo',                   /* Japanese (Windows) */
  sans-serif;

For Arabic specifically, you'll need Arabic-specific fallbacks:

font-family: 
  'Your Brand Font',
  'Noto Sans Arabic',
  'Arabic Typesetting',
  sans-serif;

Line Height Adjustments for Different Scripts

Different scripts require different line heights:

  • Latin: 1.4–1.6
  • Arabic/Hebrew: 1.6–1.8 (diacritics extend above and below)
  • Thai: 1.8–2.0 (complex consonant clusters and diacritics)
  • CJK: 1.5–1.8

Hardcoding a single line height will cause clipping in tall-ascender scripts. Use script-aware line heights in your design system:

:root { --line-height-body: 1.5; }
:lang(ar), :lang(he) { --line-height-body: 1.7; }
:lang(th) { --line-height-body: 1.9; }
:lang(zh), :lang(ja), :lang(ko) { --line-height-body: 1.6; }

Date, Time, and Number Components

Calendar and date picker components are among the most localization-intensive components in any design system.

Calendar Component Requirements

  • First day of week: Sunday (US), Monday (most of Europe and Asia), Saturday (some Middle Eastern countries)
  • Calendar system: Gregorian (default), Hebrew, Islamic (Hijri), Persian (Jalali), Buddhist (Thailand), Japanese imperial
  • Date format: MM/DD/YYYY, DD/MM/YYYY, YYYY/MM/DD, and many locale-specific variations
  • Weekend days: Saturday/Sunday (US/Europe), Friday/Saturday (Middle East), varies elsewhere
  • Holiday highlighting: If supported, must be locale-specific

Use the Intl.DateTimeFormat API for formatting and consider established headless calendar libraries (like @internationalized/date) that handle calendar system complexity.

Number Input Components

Number input components must handle locale-specific decimal separators. A German user typing "1.234,56" expects the period as a thousands separator and comma as decimal. If your input strips the period and passes "123456" to your API, you have a data integrity problem.

Currency Display

Currency components should accept:

  • Amount (as integer in smallest unit, or as Decimal)
  • Currency code (ISO 4217: USD, EUR, GBP, JPY, etc.)
  • Locale

And use Intl.NumberFormat for formatting. Never hardcode currency symbols.

Component Documentation for Localization

Great design system documentation includes localization guidance for each component:

String constraints: Document maximum character counts for each translatable string. "Button labels: max 25 characters in display font, 40 characters for compact display."

Translation notes: For UI strings in your design system (e.g., default placeholder text, built-in validation messages), include context notes for translators.

RTL variants: Show each component in both LTR and RTL in your documentation. Storybook supports locale switching that makes this straightforward.

Script examples: Show components rendering in all supported scripts, not just English.

The Localization-Ready Design System Checklist

Layout:

  • Logical CSS properties used throughout (not directional)
  • dir attribute support on root and components
  • Grid and flexbox used (not absolute positioning for layout)

Typography:

  • Multi-script font stack defined
  • Script-aware line heights
  • Font size in relative units (rem, em)
  • No fixed-width text containers

Components:

  • Buttons: min-width, not fixed width
  • Inputs: logical padding, RTL-aware icon placement
  • Modals/Drawers: RTL open direction support
  • Date pickers: locale-aware first day of week, format, calendar system
  • Number inputs: locale-aware decimal handling
  • Icons: mirrored variants for directional icons documented

Documentation:

  • String character limits documented
  • Translation context provided for built-in strings
  • RTL examples in component documentation
  • Multi-script rendering shown

Testing:

  • Storybook locale switcher configured
  • Automated visual regression in multiple locales
  • RTL smoke tests in CI

For testing approaches, see i18n testing tools, strategies, and automation.


Take your app global with better-i18n

better-i18n combines AI-powered translations, git-native workflows, and global CDN delivery into one developer-first platform. Stop managing spreadsheets and start shipping in every language.

Get started free → · Explore features · Read the docs