Internationalization & Translations
Terra supports unlimited languages through its internationalization (i18n) system. Every label, placeholder, help text, and error message can be translated—no plugins required.Architecture Overview
I18nString
Individual translatable strings stored as
{ en: "...", es: "...", zh: "..." }LocalizedDictionary
Global UI strings (buttons, errors, placeholders) stored in system settings
Form-Level Translations
Per-form translation matrix for questions, labels, and options
DeepL Integration
Auto-translate missing content with one click
The I18nString Type
Every translatable field in Terra uses theI18nString type:
getLocalizedString resolves the appropriate translation:
Global Localization Dictionary
System-wide UI strings are stored in theLocalizedDictionary structure:
Managing Global Translations
Access the global translation matrix at Settings → Localization:
| Feature | Description |
|---|---|
| Grid View | Edit translations inline with spreadsheet-style interface |
| JSON View | Direct JSON editing for bulk updates |
| Add Language | Add new languages (shows DeepL availability) |
| Auto-Translate | Fill missing translations via DeepL |
| Missing Only | Filter to show only incomplete translations |
| Column Visibility | Hide/show language columns |
Form-Level Translations
Each form has its own translation matrix for form-specific content:- Question labels
- Help text
- Placeholders
- Choice options
- Section titles
- Validation messages
Accessing Form Translations
Navigate to Forms → [Form Name] → Settings → Translations:
Translation Matrix Features
Sticky Columns
Sticky Columns
The Field and English columns stay visible when scrolling horizontally, making it easy to work with many languages.
Visual Indicators
Visual Indicators
Missing translations show a yellow corner indicator and “Missing…” placeholder. The header displays a count of incomplete fields.
Auto-Translate Column
Auto-Translate Column
Click the dropdown on any DeepL-supported language column to auto-translate all missing entries for that language.
Auto-Translate All
Auto-Translate All
The “Auto-Translate All” button fills missing translations across all visible languages simultaneously.
Grouped by Section
Grouped by Section
Translations are visually grouped by page/section for easier navigation in long forms.
DeepL Integration
Terra uses DeepL for machine translation. DeepL offers superior quality for government documents compared to other services.Setup
Add your DeepL API key to.env.local:
The
:fx suffix indicates a free API key. Paid keys don’t have this suffix.Supported Languages
| Language | Code | DeepL Support |
|---|---|---|
| English | en | ✅ Source |
| Spanish | es | ✅ Auto-translate |
| French | fr | ✅ Auto-translate |
| German | de | ✅ Auto-translate |
| Italian | it | ✅ Auto-translate |
| Portuguese | pt | ✅ Auto-translate |
| Russian | ru | ✅ Auto-translate |
| Japanese | ja | ✅ Auto-translate |
| Chinese | zh | ✅ Auto-translate |
| Korean | ko | ✅ Auto-translate |
| Arabic | ar | ✅ Auto-translate |
| Dutch | nl | ✅ Auto-translate |
| Polish | pl | ✅ Auto-translate |
| Ukrainian | uk | ✅ Auto-translate |
| Somali | so | ❌ Manual only |
| Vietnamese | vi | ❌ Manual only |
| Tagalog | tl | ❌ Manual only |
| Hindi | hi | ❌ Manual only |
| Thai | th | ❌ Manual only |
Server Actions
Two server actions power the translation features:Dev Mode Behavior
WhenDEEPL_API_KEY is not set, translations return mock values for testing:
Field-Level Auto-Translate
The form builder’s Properties Panel includes inline translation for individual fields:1
Edit a Field
Select any field in the form builder and open the Properties Panel.
2
Enter English Text
Type the label, help text, or placeholder in English.
3
Click the Sparkle Icon
Click the ✨ icon next to the input to auto-translate to all supported languages.
4
Review Translations
Switch languages in the form builder to verify translations.
Adding a New Language
To the Global Dictionary
- Go to Settings → Localization
- Click + Add Language
- Select from the categorized list (DeepL-supported vs Manual)
- Click Add Language
- Use Auto-Translate or enter translations manually
To a Form
- Go to Forms → [Form] → Settings → Translations
- Click + Add Language
- Select the language
- Click Auto-Translate All or translate manually
- Click Save
Best Practices
Always Review Auto-Translations
Machine translation is a starting point. Have native speakers review critical content like eligibility requirements.
Use Simple English
Write source text in plain language. Avoid idioms, jargon, and complex sentence structures that translate poorly.
Test with Real Users
Conduct usability testing with speakers of each supported language, especially for high-stakes forms.
Maintain Consistency
Use the same terminology throughout. “Submit” should always translate the same way across the form.
Writing for Translation
Avoid Concatenation
Avoid Concatenation
❌
"You have " + count + " items"✅ "You have {count} items" (use interpolation)Word order varies by language. Let the translation handle placement.Mind Text Expansion
Mind Text Expansion
German text is ~30% longer than English. Spanish is ~20% longer. Design UI with flexible widths.
Avoid Embedded Formatting
Avoid Embedded Formatting
❌
"Click **here** to continue"✅ Keep formatting separate from translatable strings when possible.Provide Context
Provide Context
“Save” as a noun vs verb translates differently. Use clear, unambiguous labels.
Technical Reference
Schema Flattening
Form translations use a flattening algorithm to create the translation matrix:Language Configuration
Add new languages inlib/i18n.ts:
DeepL Language Mapping
Some language codes need mapping to DeepL’s format:Troubleshooting
Auto-Translate Returns Mock Data
Auto-Translate Returns Mock Data
Check that
DEEPL_API_KEY is set in .env.local. Mock data (e.g., [ES] Hello) indicates missing or invalid API key.'Quota Exceeded' Error
'Quota Exceeded' Error
DeepL free tier has character limits. Upgrade to Pro or wait for monthly reset.
Language Not Appearing
Language Not Appearing
- Ensure it’s added to
SUPPORTED_LANGUAGESinlib/i18n.ts - Check column visibility settings (it may be hidden)
- Verify the language was saved to the form/dictionary
Translations Not Saving
Translations Not Saving
Click Save after editing. Changes are not auto-saved. Check browser console for errors.
Flickering/Re-renders in Matrix
Flickering/Re-renders in Matrix
The translation matrix uses optimized rendering with memoization. If experiencing performance issues with many languages, hide unused columns.
Back to Setup Guide
Return to the local development setup guide.