TL;DR: Multi-language email templates require careful design — locale-aware content, template inheritance, dynamic subject lines, and robust fallback chains. This guide covers architecture and implementation. Patterns from tanstackship.com.
Introduction
Email is a critical communication channel for SaaS, and sending emails in the wrong language damages trust. A proper multi-language email system handles translations, locale-specific formatting, and content variations across 10+ languages without duplicating templates. For broader i18n strategy, see our i18n for SaaS: Architecture Patterns Compared.
Email Template Architecture
| Component | Responsibility | Example |
|---|---|---|
| Template engine | Render HTML with variables | Handlebars, MJML, React Email |
| Translation service | Locale-aware content | Paraglide.js JSON files |
| Formatting service | Locale-aware numbers/dates | Intl API |
| Image service | Locale-specific images | CDN with locale path |
| Fallback chain | Missing translation handling | target → en → key |
Template Structure
emails/
├── en/
│ ├── welcome.html # English version
│ ├── welcome.subject # Subject line only
│ ├── invoice.html
│ └── invoice.subject
├── de/
│ ├── welcome.html
│ ├── welcome.subject
│ ├── invoice.html
│ └── invoice.subject
└── shared/
├── header.html # Shared components
├── footer.html
└── styles.css
Implementation with React Email
// React Email component with i18n
import * as m from '~/paraglide/messages.js'
import {
Body, Container, Head, Heading, Html,
Preview, Section, Text, Button,
} from '@react-email/components'
interface WelcomeEmailProps {
userName: string
locale: string
dashboardUrl: string
}
export function WelcomeEmail({ userName, locale, dashboardUrl }: WelcomeEmailProps) {
return (
<Html>
<Head />
<Preview>{m.email_welcome_preview({ name: userName })}</Preview>
<Body>
<Container>
<Heading>{m.email_welcome_title({ name: userName })}</Heading>
<Text>{m.email_welcome_body()}</Text>
<Section>
<Button href={dashboardUrl}>
{m.email_welcome_cta()}
</Button>
</Section>
<Text style={{ fontSize: '12px', color: '#666' }}>
{m.email_welcome_footer()}
</Text>
</Container>
</Body>
</Html>
)
}
Dynamic Subject Lines
// Subject line per locale, with variables
const subjectTemplates = {
en: 'Welcome to TanStack Ship, {name}!',
de: 'Willkommen bei TanStack Ship, {name}!',
zh: '{name},欢迎使用 TanStack Ship!',
ja: '{name}さん、TanStack Shipへようこそ!',
ar: 'مرحبًا {name} في TanStack Ship!',
}
function getSubject(template: string, locale: string, vars: Record<string, string>) {
let subject = subjectTemplates[locale] || subjectTemplates['en']
Object.entries(vars).forEach(([key, value]) => {
subject = subject.replace(`{${key}}`, value)
})
return subject
}
Sending with Fallback
// Email sending with locale fallback
async function sendEmail({
to,
locale,
template,
data,
}: {
to: string
locale: string
template: string
data: Record<string, any>
}) {
const effectiveLocale = SUPPORTED_LOCALES.includes(locale) ? locale : 'en'
// Load template with fallback chain
const html = await loadTemplate(template, effectiveLocale, data)
const subject = await loadSubject(template, effectiveLocale, data)
await sendEmailClient({
to,
subject,
html,
headers: {
// Track language for analytics
'X-Email-Locale': effectiveLocale,
},
})
}
Testing Multi-Language Emails
| Test Case | Method | What to Check |
|---|---|---|
| All locales render | Automated render test | No missing keys, no errors |
| Subject line length | Character count | Arabic/Chinese subjects may be shorter |
| RTL rendering | Visual inspection | Arabic emails read right-to-left |
| Date/number format | Snapshot test | Locale-correct formatting |
| Fallback behavior | Test with unsupported locale | Graceful fallback to en |
Conclusion
Use a single template system with locale-specific content files. React Email components with Paraglide.js provide type-safe translations. Always render a fallback locale when a translation is missing. Test every email template in all supported locales as part of your CI pipeline.
For locale-aware formatting in emails, see Localizing Date, Time, Number, and Currency Formats. Our SaaS Email Deliverability Guide covers SPF, DKIM, and DMARC setup. For building locale-specific marketing pages, check out Building a Language-Specific Landing Page Strategy.