Skip to main content

Multilingual Templates

docs101 templates support multiple languages through a JSON-based translation system. This guide explains how to define translation keys, use them in your templates, and test multi-language invoices.

How the Translation System Works

The translation system follows four steps:

  1. Define translations: In the template's Translations tab, define text keys with their translations for each supported language as a JSON object
  2. Use keys in template code: Reference translation keys in your HTML using {{ t('key_name') }}
  3. Automatic language selection: When generating an invoice, docs101 selects the correct language based on the customer's language preference (English or German)
  4. Fallback: If a translation key is missing for the customer's language, the system falls back to the available translations

Translation Data Structure

Translations are stored as a JSON object on the template. The top-level keys are language codes (en, de), and each contains a flat key-value map:

{
"en": {
"invoice_title": "Invoice",
"invoice_number": "Invoice #:",
"date_label": "Date:",
"due_date_label": "Due:",
"bill_to": "Bill To",
"col_description": "Description",
"col_quantity": "Qty",
"col_unit_price": "Unit Price",
"col_total": "Total",
"subtotal": "Subtotal",
"vat_label": "VAT",
"total": "Total Amount",
"payment_terms": "Payment Terms",
"thank_you": "Thank you for your business!"
},
"de": {
"invoice_title": "Rechnung",
"invoice_number": "Rechnungsnummer:",
"date_label": "Datum:",
"due_date_label": "Fällig:",
"bill_to": "Rechnungsempfänger",
"col_description": "Beschreibung",
"col_quantity": "Menge",
"col_unit_price": "Einzelpreis",
"col_total": "Summe",
"subtotal": "Zwischensumme",
"vat_label": "USt.",
"total": "Gesamtsumme",
"payment_terms": "Zahlungsbedingungen",
"thank_you": "Vielen Dank für Ihr Geschäft!"
}
}

Editing Translations in the Template IDE

Open any template in the Template IDE and click the Translations tab:

  1. The Translations tab shows the current translation JSON
  2. Edit the JSON directly to add, modify, or remove translation keys
  3. Ensure each language section (en, de) contains the same set of keys
  4. Click Save to persist your changes
Keep Keys Consistent

Always define the same set of keys in every language section. If you add a new key to en, immediately add it to de as well — and vice versa. This prevents missing translations in generated documents.

Using Translations in Templates

The t() Function

Reference any translation key in your template HTML using the t() function:

{{ t('invoice_title') }}
{{ t('thank_you') }}
{{ t('payment_terms') }}

When the PDF is generated, t('invoice_title') outputs "Invoice" for English-speaking customers and "Rechnung" for German-speaking customers.

Example: Translating the Invoice Header

Translations JSON (excerpt):

{
"en": { "invoice_title": "Invoice", "invoice_number": "Invoice #:" },
"de": { "invoice_title": "Rechnung", "invoice_number": "Rechnungsnummer:" }
}

Header HTML:

<h1>{{ t('invoice_title') }}</h1>
<p>{{ t('invoice_number') }} {{ invoice.invoice_number }}</p>

Result for an English customer: Invoice / Invoice #: INV-2024-001 Result for a German customer: Rechnung / Rechnungsnummer: INV-2024-001

Example: Translating Table Column Headers

Translations JSON (excerpt):

{
"en": { "col_description": "Description", "col_quantity": "Qty", "col_unit_price": "Unit Price", "col_total": "Total" },
"de": { "col_description": "Beschreibung", "col_quantity": "Menge", "col_unit_price": "Einzelpreis", "col_total": "Summe" }
}

Invoice Content HTML:

<table class="invoice-items">
<thead>
<tr>
<th>{{ t('col_description') }}</th>
<th>{{ t('col_quantity') }}</th>
<th>{{ t('col_unit_price') }}</th>
<th>{{ t('col_total') }}</th>
</tr>
</thead>
<tbody>
{% for position in positions %}
<tr>
<td>{{ position.title }}</td>
<td>{{ position.quantity }}</td>
<td>{{ position.unit_price }}</td>
<td>{{ position.total }}</td>
</tr>
{% endfor %}
</tbody>
</table>

Translations JSON (excerpt):

{
"en": { "bank_details": "Bank Details", "terms_notice": "Terms and conditions apply" },
"de": { "bank_details": "Bankdaten", "terms_notice": "Allgemeine Geschäftsbedingungen gelten" }
}

Footer HTML:

<div class="invoice-footer">
<h3>{{ t('bank_details') }}</h3>
<p>{{ bank_account.bank_name }} - IBAN: {{ bank_account.iban }}</p>
<p class="small-text">{{ t('terms_notice') }}</p>
</div>

How Language Selection Works

Customer Language Preference

Each customer in docs101 has a language setting (e.g., "English" or "German"). When generating an invoice or account statement:

  1. docs101 reads the customer's language preference
  2. Maps it to a language code (English -> en, German -> de)
  3. Loads the corresponding translation keys from the template's translations JSON
  4. The t() function in the template resolves to the correct language values

Setting a Customer's Language

  1. Go to the Customers section
  2. Edit the customer
  3. Set the Language field to English or German
  4. Save changes

All future invoices for this customer will use their selected language.

Preview Language

The Template IDE preview loads the English (en) translations by default. To see how your template looks in German, generate a test invoice for a customer whose language is set to German.

Best Practices for Translation Keys

Naming Conventions

  • Use lowercase with underscores: invoice_title, col_description, payment_terms
  • Be descriptive: invoice_number_label is clearer than num
  • Use prefixes for grouping: col_ for table columns, payment_ for payment-related text
  • Keep names concise but meaningful

Content Guidelines

  • Translate everything: All user-facing text in the template should use t() — do not hardcode text in any language
  • Keep translations short: Longer text in one language may break layouts, especially in narrow table columns. German text is often longer than English equivalents, so test both
  • Be consistent: Use the same term throughout (e.g., always "Invoice" not sometimes "Bill")
Layout Impact

German translations are typically 20-30% longer than English. Test your template with German text to ensure tables and labels do not overflow or break the layout.

Testing Multilingual Templates

Step-by-Step Testing

  1. Open your template in the Template IDE and verify the preview looks correct (English translations)
  2. Create a test customer with language set to German
  3. Create a test invoice for that customer
  4. Generate the PDF and verify all text appears in German
  5. Check that no translation keys are missing (look for empty text where labels should be)
  6. Repeat with an English customer to confirm both languages work

Checking for Missing Translations

If a translation key is referenced in the template but not defined in the translations JSON for the customer's language:

  • The output will show an empty string where the translated text should appear
  • Review your template output carefully and compare against the translations JSON to identify missing keys

Supported Languages

docs101 currently maps customer language preferences to these language codes:

Customer LanguageCode
Englishen
Germande

You can add translation keys for additional languages in the JSON structure. The language code used must match what the backend maps from the customer's language preference.


Ready to build a complete template from scratch? Continue to Create from Scratch to walk through building a fully functional, multi-language invoice template step by step.