Defining Translations
Translations live in a version-controlledtranslations.yaml file at the project root, alongside evidence.config.yaml and theme.yaml. They apply to every page in the project — there is no per-page translations file.
Translations are defined in YAML format with 2-digit language codes (e.g., en, fr, es, de) as top-level keys. (Language Codes)
Nested Translations
You can organize translations into groups:Reusing Translations
Translations support i18next nesting syntax for reusing translations within other translations:$translations.report_title becomes “Q4 Revenue Report” in English or “Rapport Chiffre d’affaires T4” in French.
Using Translations in Pages
Translations are accessible via the special$translations variable.
Inline in Text
In Component Attributes
Templated in Strings
In SQL
Using Translations Inside SQL String Literals
Translation values often contain apostrophes (d'affaires, l'offre, chiffre d'affaires). Interpolating them raw into a '…' SQL string literal closes
the literal early and the warehouse rejects the query. Use the .sql
accessor in that position — Evidence escapes the value using the target
warehouse’s own string-literal rules (doubled quote '' on Postgres, DuckDB,
ClickHouse, Snowflake; backslash-escaped \' on BigQuery, Databricks):
Offre d'adhérents:
- On Postgres / DuckDB / ClickHouse / Snowflake:
where section = 'Offre d''adhérents' - On BigQuery / Databricks:
where section = 'Offre d\'adhérents'
Offre d'adhérents) — the escape is SQL
syntax only, never text the reader sees.
Use .sql only inside a single-quoted SQL string literal. Elsewhere —
plain text, headings, identifier concatenation like label_{{ $translations.langcode }} — the bare form is correct and .sql would
incorrectly rewrite apostrophes that were never inside a SQL literal.
Built-in Report Text
translations.yaml covers your content. Everything Evidence itself draws inside a report follows the selected language automatically, with no translation keys required:
- Chart date axes and tooltips — both the words (month abbreviations, quarter labels) and the conventions (day-month order, punctuation, 12/24-hour clock) switch.
- Component text — table pagination and search, filter chips and operators, dropdown and date range picker labels and presets, legend “show more”, the “Download” button, sampling notices, computed “Total” labels, and similar.
Currently supported: English (
en) and French (fr). Regional variants such as fr-CA use the base language; any other language renders English built-in text (your translations.yaml content is unaffected).
Component attributes you set explicitly always win over the built-in text — total_label="Net" on a waterfall chart stays Net in every language. Leave the attribute out to get the translated default, or pass total_label=$translations.net to translate it yourself.
Custom date formats
Explicit date formats keep working and translate their month and weekday names, whereverfmt is used — chart axes, tooltips, tables, big values. Numeric tokens, separators and quoted literals are left exactly as written:
Named presets whose English definition carries English word order or a 12-hour clock are redefined per language: in French
longdate is 15 janvier 2025, fulldate is mercredi 15 janvier 2025 and hms is 16:05:09. AM/PM has no French form and stays as written.
Contributing a Language
Built-in text lives in the open-source Evidence repository. UI strings are standard i18next JSON resources (the same library that resolvestranslations.yaml) and date formats are date-fns locale configurations, so a new language is a small, self-contained pull request: one JSON file, one date config, and a one-line registration. The test suite verifies the files are complete. See core/src/locale/README.md for the step-by-step guide.
Fallback Behavior
If a translation key is missing for the selected language, it will fall back to English (en) if available.
