Bug description
Embedded dashboards are never translated: the embedded entry point does not run the i18n bootstrap
Bug description
Embedded dashboards always render Superset's own UI strings in English, regardless of BABEL_DEFAULT_LOCALE, LANGUAGES, or the locale resolved for the embedded page.
The regular (logged-in) app translates correctly with the same configuration. Only the embedded SPA is affected.
The cause is not locale resolution and not the translation catalogs — both are correct. The embedded entry point simply never performs the i18n setup that the main app performs, so /superset/language_pack/<locale>/ is never requested and the i18n singleton stays at its English default.
This is a regression in behaviour relative to what is described in discussion #22536, where users at least saw Error loading language pack ..., falling back on en in embedded dashboards — i.e. the fetch was attempted and failed. In 6.1.0 it is not attempted at all.
Evidence
1. The embedded page resolves a non-English locale correctly.
GET /embedded/<embedded-uuid> returns bootstrap data containing:
{ "common": { "locale": "pt", ... } }
So the server side is fine — the page knows it should be Portuguese.
2. The language pack endpoint works and returns a populated catalog.
GET /superset/language_pack/pt/ -> 200, 4245 strings ("No filter" -> "Sem filtro", "Apply" -> "Aplicar")
3. The browser never requests it when loading an embedded dashboard.
Access log for a browser session that loaded an embedded dashboard three times (filtered to browser user-agents):
35 "POST /api/v1/chart/data
19 "POST /superset/log/
5 "GET /static/service-worker.js
4 "GET /api/v1/me/roles/
3 "GET /embedded/1200405b-xxxx-xxxx-xxxx-xxxxxxxxxxxx
3 "GET /api/v1/dashboard/18/datasets
3 "GET /api/v1/dashboard/18/charts
There is no request to /superset/language_pack/ from any browser user-agent. The only hits on that endpoint in the whole log are from my own diagnostic client (axios/1.16.1).
4. The embedded bundle contains no i18n code.
The code that fetches the pack lives in a shared chunk (616.<hash>.entry.js), which the embedded page does load:
let x = $.common.locale || "en";
if ("en" !== x) {
const t = getUrl(`/superset/language_pack/${x}/`);
const r = await fetch(t, { signal });
if (!r.ok) throw Error(`Failed to fetch language pack: ${r.status}`);
configure({ languagePack: await r.json() });
}
…but the embedded entry point itself never triggers it. embedded.<hash>.entry.js is ~26 KB and contains zero occurrences of any of:
locale 0
i18n 0
languagePack 0
getUrl 0
It appears superset-frontend/src/embedded/index.tsx does not run the preamble/bootstrap step that the main app runs, so configure({ languagePack }) is never called for embedded dashboards.
How to reproduce
- Configure a non-English locale, e.g.:
BABEL_DEFAULT_LOCALE = "pt_BR"
LANGUAGES = {
"pt_BR": {"flag": "br", "name": "Brazilian Portuguese"},
"en": {"flag": "us", "name": "English"},
}
- Make sure the catalogs are compiled (see "Additional context" — the official image ships only
.po).
- Open Superset normally → UI is translated.
- Embed any dashboard with
@superset-ui/embedded-sdk → UI is in English ("Filters and controls", "No filter", "Edit time range", "CANCEL", "APPLY").
- Check the server access log: no request to
/superset/language_pack/<locale>/ is made by the browser.
Expected results
The embedded dashboard should load the language pack for the resolved locale and render Superset's UI strings translated, as the main app does.
Actual results
The language pack is never fetched. Superset's UI strings inside the embedded dashboard are always English. Only user-authored content (chart titles, metric labels, native filter names) appears in the configured language, because those come from the dashboard's own data.
Environment
- Superset:
apache/superset:6.1.0 (official image, Helm chart)
- Embedding:
@superset-ui/embedded-sdk, guest token auth
- Feature flags:
EMBEDDED_SUPERSET: True, DASHBOARD_RBAC: True
- Browser: Chrome
Additional context
Two adjacent findings from the same investigation, in case they are useful:
a) The official image ships uncompiled catalogs. /app/superset/translations/<locale>/LC_MESSAGES/ contains only messages.po — no messages.mo (gettext, backend) and no messages.json (the file /superset/language_pack/<lang>/ serves). Only empty_language_pack.json is present. This means a fresh 6.1.0 deployment is untranslated even for the logged-in app until you run pybabel compile yourself and generate the JSON catalogs. Is this intentional?
b) /superset/language_pack/<lang>/ is @has_access. Even if the embedded entry did fetch it, the call in the bundle is a bare fetch() with no Authorization header, so it is anonymous and gets a 302 to /login/ — the guest token is not sent. Granting can_language_pack on Superset to the guest role does not help for that reason; it would have to go to the Public role. If the embedded i18n path is restored, this endpoint likely needs to accept guest tokens (or be exempt from @has_access).
Related: #22536
Screenshots/recordings
No response
Superset version
master / latest-dev
Python version
3.11
Node version
16
Browser
Chrome
Additional context
No response
Checklist
Bug description
Embedded dashboards are never translated: the embedded entry point does not run the i18n bootstrap
Bug description
Embedded dashboards always render Superset's own UI strings in English, regardless of
BABEL_DEFAULT_LOCALE,LANGUAGES, or the locale resolved for the embedded page.The regular (logged-in) app translates correctly with the same configuration. Only the embedded SPA is affected.
The cause is not locale resolution and not the translation catalogs — both are correct. The embedded entry point simply never performs the i18n setup that the main app performs, so
/superset/language_pack/<locale>/is never requested and the i18n singleton stays at its English default.This is a regression in behaviour relative to what is described in discussion #22536, where users at least saw
Error loading language pack ..., falling back on enin embedded dashboards — i.e. the fetch was attempted and failed. In 6.1.0 it is not attempted at all.Evidence
1. The embedded page resolves a non-English locale correctly.
GET /embedded/<embedded-uuid>returns bootstrap data containing:{ "common": { "locale": "pt", ... } }So the server side is fine — the page knows it should be Portuguese.
2. The language pack endpoint works and returns a populated catalog.
3. The browser never requests it when loading an embedded dashboard.
Access log for a browser session that loaded an embedded dashboard three times (filtered to browser user-agents):
There is no request to
/superset/language_pack/from any browser user-agent. The only hits on that endpoint in the whole log are from my own diagnostic client (axios/1.16.1).4. The embedded bundle contains no i18n code.
The code that fetches the pack lives in a shared chunk (
616.<hash>.entry.js), which the embedded page does load:…but the embedded entry point itself never triggers it.
embedded.<hash>.entry.jsis ~26 KB and contains zero occurrences of any of:It appears
superset-frontend/src/embedded/index.tsxdoes not run the preamble/bootstrap step that the main app runs, soconfigure({ languagePack })is never called for embedded dashboards.How to reproduce
.po).@superset-ui/embedded-sdk→ UI is in English ("Filters and controls", "No filter", "Edit time range", "CANCEL", "APPLY")./superset/language_pack/<locale>/is made by the browser.Expected results
The embedded dashboard should load the language pack for the resolved locale and render Superset's UI strings translated, as the main app does.
Actual results
The language pack is never fetched. Superset's UI strings inside the embedded dashboard are always English. Only user-authored content (chart titles, metric labels, native filter names) appears in the configured language, because those come from the dashboard's own data.
Environment
apache/superset:6.1.0(official image, Helm chart)@superset-ui/embedded-sdk, guest token authEMBEDDED_SUPERSET: True,DASHBOARD_RBAC: TrueAdditional context
Two adjacent findings from the same investigation, in case they are useful:
a) The official image ships uncompiled catalogs.
/app/superset/translations/<locale>/LC_MESSAGES/contains onlymessages.po— nomessages.mo(gettext, backend) and nomessages.json(the file/superset/language_pack/<lang>/serves). Onlyempty_language_pack.jsonis present. This means a fresh 6.1.0 deployment is untranslated even for the logged-in app until you runpybabel compileyourself and generate the JSON catalogs. Is this intentional?b)
/superset/language_pack/<lang>/is@has_access. Even if the embedded entry did fetch it, the call in the bundle is a barefetch()with noAuthorizationheader, so it is anonymous and gets a 302 to/login/— the guest token is not sent. Grantingcan_language_pack on Supersetto the guest role does not help for that reason; it would have to go to thePublicrole. If the embedded i18n path is restored, this endpoint likely needs to accept guest tokens (or be exempt from@has_access).Related: #22536
Screenshots/recordings
No response
Superset version
master / latest-dev
Python version
3.11
Node version
16
Browser
Chrome
Additional context
No response
Checklist