[Upcoming] Localization for embedded analytics
This feature is not yet available. This document is not final and may change during development. We'll update this page when it launches.
Introduction
If your customers speak different languages, they expect dashboards in their own language. With localization, you build a dashboard once, add translations for each language, and each viewer sees the right one.
Here is the same dashboard, viewed by an English speaker and a French speaker:
What gets localized
The content on a dashboard comes from a few different places, and each one is handled differently. Some of it Holistics localizes for you, and some of it you own.
| Content | Examples | Who localizes it |
|---|---|---|
| System texts | Buttons, menus, notifications, error messages | Holistics. Unsupported languages fall back to English |
| Dashboard texts | Dashboard and viz titles, text blocks, field labels, and labels from your datasets and models | You, in translation files |
| Data values | Product names and categories from your database | You, in your database, picked in your AML model |
Which language each viewer gets depends on the locale you pass in the embed payload. See Step 5.
Set up localization
You translate dashboard texts and data values in your AML project, check them in Development, publish, and then tell Holistics which locale each viewer uses.
Step 1. Translate dashboard texts
You translate dashboard texts once in translation files, and Holistics applies the right file to each viewer. At view time, it replaces each authored text with its translation for the viewer's locale, so one dashboard serves every language.
Find your translation keys. Every text authored in your dashboards, datasets, and models is a translation key, such as the dashboard title, viz block and filter labels, field labels, and text block content. In the Hooli Home dashboard below, each boxed text is a key:
A key doesn't have to be the source text. It can be plain text or follow any naming convention you like, such as ecommerce dashboard title or $ecommerce_dashboard_title. If you use a custom key, add an entry for it in every locale file, including English, so viewers never see the raw key.
Create a translation file per locale. Add one JSON file per locale under settings/locales/ in the AML repo, named after the exact locale you pass in the embed payload: viewers with settings.locale: "fr-FR" get fr-FR.json. Each entry maps a key to its translation:
{
"Hooli Home": "Accueil Hooli",
"Sales": "Ventes",
"Orders": "Commandes",
"Buyers by Country": "Acheteurs par pays",
"Top 10 Most Ordered Products": "Top 10 des produits les plus commandés",
"User Country": "Pays de l'utilisateur"
}
If a text has no matching entry in the translation file, Holistics shows the original text as is. Nothing errors and nothing renders blank, so untranslated strings simply appear in their source language.
Keys match whole texts, not individual words. Translating "Sales" doesn't change "Monthly Sales", so give each text its own entry.
Once you use translations, we recommend changing text in your translation files rather than in your dashboards, models, or datasets. If your keys are the source texts, editing a text there changes its key, and the translations for other languages stop applying.
Step 2. Translate data values
Data values come straight from your database, so Holistics can't translate them. Store the translations in your data, then pick the right one in your model.
Start by keeping a column per language:
| name | name_fr_fr | name_es_es |
|---|---|---|
| Face Mask | Masque visage | Mascarilla facial |
| Dining Chair 2 | Chaise de salle à manger 2 | Silla de comedor 2 |
| Diesel Jeans | Jean Diesel | Vaqueros Diesel |
Then use AML to show the right column based on H.current_locale, the viewer's locale from the embed payload. Redefine the dimension you already use, such as name, so existing charts and tables pick up the localized value:
dimension name {
label: 'Name'
type: 'text'
definition: if (H.current_locale == 'fr-FR') {
@sql {{ #SOURCE.name_fr_fr }};;
} else if (H.current_locale == 'es-ES') {
@sql {{ #SOURCE.name_es_es }};;
} else {
@sql {{ #SOURCE.name }};;
}
}
Handle missing translations
If some rows don't have a translation yet, viewers in that locale see an empty value. To show the English value instead, wrap each translated column in coalesce. Add nullif(..., '') if missing translations are stored as empty strings rather than NULL:
dimension name {
label: 'Name'
type: 'text'
definition: if (H.current_locale == 'fr-FR') {
@sql coalesce(nullif({{ #SOURCE.name_fr_fr }}, ''), {{ #SOURCE.name }});;
} else if (H.current_locale == 'es-ES') {
@sql coalesce(nullif({{ #SOURCE.name_es_es }}, ''), {{ #SOURCE.name }});;
} else {
@sql {{ #SOURCE.name }};;
}
}
For example, a viewer with fr-FR sees Masque visage where an English viewer sees Face Mask.
Step 3. Preview in Development
Before publishing, check your translations in Development. Open a dashboard or an exploration, pick a language from Preview locale, and both dashboard texts and data values render in that locale. This only changes your preview, not what your viewers see.
Step 4. Publish
Publish your translation files and model changes to production so your embedded dashboards can use them.
Step 5. Set the viewer's locale
Holistics decides which language to show based on the viewer's locale. A locale is identified by a BCP 47 language tag, a language plus a region such as en-US, fr-FR, or vi-VN.
Set it per viewer with settings.locale in the embed payload, so your application decides the locale for each embed user:
const embed_payload = {
// ... other settings
settings: {
locale: "fr-FR"
}
}
To try a locale before wiring it into your app, use the Embed Builder on the Embedded Analytics page. Pick a language under Settings > Interface language, and the builder sets settings.locale in the payload for you:


What the viewer sees
Each viewer sees the same dashboard in their own language, with translated dashboard texts and data values. For example, a viewer with locale: "fr-FR" sees this:
Not in scope
This first version focuses on embedded analytics. A few things are not covered yet:
- Built-in language switcher: the embedded dashboard has no language switcher. To let viewers change language, add a switcher to your application and pass the chosen locale in
settings.localeof the embed payload. - Right-to-left languages, such as Arabic and Hebrew.
- Timezone and week start, which are existing settings separate from locale.
- The date filter's matches operator, which accepts natural language time expressions.
FAQ
Find answers to common questions about localizing your embedded dashboards and integrating with other Holistics features.
Does localization work with Ask AI (conversational analytics)?
Yes. You can tell the AI to reply in the viewer's language by referencing H.current_locale in your custom AI context file. Map each locale to a language name, then add a language section to your AI context:
const ai_language = if (H.current_locale == 'es-ES') {
'Spanish (Spain)'
} else if (H.current_locale == 'fr-FR') {
'French (France)'
} else if (H.current_locale == 'ja-JP') {
'Japanese'
} else {
'English'
}
const ai_context = @md
## Language
- My locale is ${H.current_locale}. Always reply in ${ai_language}, including headings, explanations, chart titles and suggested follow-up questions.
- Product, category and country names in the data are already shown in my language; quote them as they appear.
- Keep dataset, model and field names, AQL, and code exactly as they are. Don't translate them.
;;
Since H.current_locale comes from the same locale you pass in the embed payload, each embedded viewer gets AI answers in their own language.
Can embed users with self-service permissions create content?
Yes. They create content in their own language as usual, and system texts still follow their locale. Content they create isn't translated for other viewers, since translation files only cover content your analysts author in AML.
Related resources
- Embed payload reference: Full list of embed payload options, including
settings.locale - AML if-else: The conditional expression used to localize data values
- Custom AI context: Tell Ask AI to reply in the viewer's language