Torna al Blog
Tutorials

How to Localize Email Templates: A Complete Developer Guide

Email is still the highest-ROI channel for most SaaS companies. But most teams localize their product UI and completely forget about their emails —...

Ali Osman Delismen9 min di lettura

Email is still the highest-ROI channel for most SaaS companies. But most teams localize their product UI and completely forget about their emails — sending English welcome emails to users in Brazil, billing alerts to Japanese customers in a language they may not read fluently, and onboarding sequences that ignore cultural context entirely.

This guide covers everything you need to know about email template localization: what to translate, how to handle dynamic variables, RTL language support, and how to build a workflow that scales without turning your engineering team into professional translators.

Why Email Localization Is Harder Than UI Localization

Localizing a button label is straightforward. Localizing an email is a different beast:

  • Rich formatting — HTML emails have complex layouts that break with longer text in German or shorter text in Chinese
  • Dynamic variablesHello {{name}}, your {{plan}} subscription renews on {{date}} needs to handle variable ordering that differs by language
  • Plural forms — "You have 1 message" vs "You have 3 messages" — ICU MessageFormat handles this, but most email tools don't
  • RTL languages — Arabic and Hebrew require mirrored layouts, right-aligned text, and directional HTML attributes
  • Date and number formatting — December 3 in the US is 3. Dezember in Germany and ٣ ديسمبر in Arabic
  • Tone and formality — German business emails use formal "Sie", Japanese has honorifics, Brazilian Portuguese is warmer than European Portuguese

These aren't reasons to avoid email localization — they're reasons to build it properly from the start.

Step 1: Audit Your Email Templates

Before writing a single line of code, inventory every email your product sends:

Transactional emails (highest priority):

  • Welcome / account created
  • Email verification
  • Password reset
  • Payment confirmation / receipt
  • Subscription renewal reminder
  • Invoice / billing
  • Account suspension / deletion warning

Engagement emails (medium priority):

  • Onboarding sequences (day 1, day 3, day 7)
  • Feature announcement
  • Usage milestones ("You've reached 1,000 translations!")
  • Re-engagement campaigns

Operational emails (lower priority, but still important for enterprise):

  • Team invitation
  • Role change notification
  • API key expiration warning
  • Maintenance alerts

For each email, note: does it contain dynamic variables? Plural forms? Dates? User-generated content? This informs your localization approach.

Step 2: Separate Content from Template Structure

The most common mistake is embedding translated text directly in HTML templates. Instead, treat email content like you treat your UI — use a key-value translation system.

The wrong approach

<!-- en/welcome.html -->
<h1>Welcome to Better i18n, {{firstName}}!</h1>
<p>You're all set to start localizing your app.</p>

<!-- de/welcome.html -->
<h1>Willkommen bei Better i18n, {{firstName}}!</h1>
<p>Sie können jetzt mit der Lokalisierung Ihrer App beginnen.</p>

Maintaining 8 copies of every email template for 8 languages is a nightmare. Change the layout once and you have 8 files to update.

The right approach

<!-- welcome.html (single template) -->
<h1>{{t "email.welcome.heading" firstName=firstName}}</h1>
<p>{{t "email.welcome.body"}}</p>
// en.json
{
  "email": {
    "welcome": {
      "heading": "Welcome to Better i18n, {firstName}!",
      "body": "You're all set to start localizing your app."
    }
  }
}

// de.json
{
  "email": {
    "welcome": {
      "heading": "Willkommen bei Better i18n, {firstName}!",
      "body": "Sie können jetzt mit der Lokalisierung Ihrer App beginnen."
    }
  }
}

This gives you one template, N translation files.

Step 3: Use ICU MessageFormat for Variables and Plurals

ICU MessageFormat is the industry standard for handling complex localization cases in strings. Most modern i18n libraries support it — and you should use it for email copy too.

Basic variable substitution

"email.welcome.heading" = "Welcome to Better i18n, {firstName}!"

Plural forms

"email.usage.messages" = "{count, plural, one {You have # unread message.} other {You have # unread messages.}}"

This automatically handles "1 message" vs "3 messages" — and Russian, which has four plural forms.

Date formatting

Rather than passing pre-formatted dates as strings, pass ISO timestamps and format them in the template engine with the locale context:

// Instead of:
t('email.renewal', { date: 'December 3, 2025' }) // wrong locale format

// Do:
t('email.renewal', { date: new Date('2025-12-03') })
// Result in en: "December 3, 2025"
// Result in de: "3. Dezember 2025"
// Result in ja: "2025年12月3日"

Step 4: Handle RTL Languages

Arabic and Hebrew are right-to-left, which affects your entire email layout. Add dir attribute based on locale:

<!DOCTYPE html>
<html dir="{{direction}}" lang="{{locale}}">
const direction = ['ar', 'he', 'fa', 'ur'].includes(locale) ? 'rtl' : 'ltr';

For RTL emails:

  • Text aligns right by default
  • Use logical CSS properties: padding-inline-start: 24px instead of padding-left
  • Icons and arrows that indicate direction need mirrored versions
  • Multi-column layouts may need to flip column order

Test your RTL emails in Gmail, Apple Mail, and Outlook — each handles dir differently.

Step 5: Build a Translation Workflow for Email Content

Option A: Manual process (doesn't scale)

Export string files → send to translation vendor → wait → import back → hope nothing broke. Works for 2 languages. Falls apart at 8.

Option B: Automated with Better i18n

Better i18n treats email translation keys the same as UI translation keys:

{
  "email.welcome.subject": "Welcome to Better i18n!",
  "email.welcome.heading": "Welcome, {firstName}!",
  "email.welcome.body": "Your account is ready. Let's get started.",
  "email.welcome.cta": "Open Dashboard"
}

Sync via CLI or GitHub integration, use AI translation for speed, review for quality, then access at send time:

import { loadTranslations } from '@better-i18n/core';

async function sendWelcomeEmail(user: User) {
  const t = await loadTranslations(user.locale, 'email');

  await emailProvider.send({
    to: user.email,
    subject: t('email.welcome.subject'),
    html: renderTemplate('welcome', {
      heading: t('email.welcome.heading', { firstName: user.firstName }),
      body: t('email.welcome.body'),
      cta: t('email.welcome.cta'),
      direction: getDirection(user.locale),
      locale: user.locale,
    }),
  });
}

Step 6: Test Your Localized Emails

Content testing:

  • All variables render correctly in each locale
  • Pluralization works for edge cases (0, 1, 2, 11, 100)
  • Long German/Finnish text doesn't break layout
  • Short Chinese/Japanese text doesn't look sparse

Visual testing:

  • RTL layout renders correctly in Gmail, Outlook, Apple Mail
  • Images have localized alt text
  • CTA button text fits correctly in all languages

Use a tool like Litmus or Email on Acid for cross-client rendering, and test at least 3 representative languages (Western Latin, RTL, and Asian).

Common Mistakes to Avoid

Hardcoding locale-specific assumptions — Don't assume all users have first + last names, that dates use MM/DD/YYYY, or that phone numbers have 10 digits.

Translating emails last — Email localization requires different expertise than UI localization. Plan for it from the start.

Ignoring email client limitations — Some clients strip <style> tags. Test your RTL layout in Outlook specifically.

Not updating translations when copy changes — Better i18n's translation key system flags untranslated or outdated keys automatically.

The Business Case for Email Localization

Numbers from SaaS companies that have invested in email localization:

  • 35-50% higher open rates for emails in the recipient's native language
  • 20-30% higher click-through rates on localized CTAs
  • Reduced churn in non-English markets where product value was communicated in English
  • Enterprise deals unlocked when procurement teams can review billing communications in their language

The ROI on email localization is typically 3-6 months for SaaS companies targeting multiple language markets.

Getting Started

  1. Audit your 3 highest-impact transactional emails (welcome, billing, password reset)
  2. Extract all strings into a translation system (Better i18n or equivalent)
  3. Translate to your top 2-3 non-English markets
  4. Set up automated sync so new email copy gets flagged for translation
  5. Expand from there

Better i18n makes steps 2-4 dramatically faster — your email strings live alongside your UI strings, AI translation handles the first pass, and GitHub sync keeps everything in sync automatically.

Start localizing your emails free →

Commenti

Loading comments...

Related

Articoli correlati