Skip to content

Embedded dashboards are never translated: the embedded entry point does not run the i18n bootstrap #42433

Description

@rogaha

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

  1. 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"},
    }
  2. Make sure the catalogs are compiled (see "Additional context" — the official image ships only .po).
  3. Open Superset normally → UI is translated.
  4. Embed any dashboard with @superset-ui/embedded-sdk → UI is in English ("Filters and controls", "No filter", "Edit time range", "CANCEL", "APPLY").
  5. 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

  • I have searched Superset docs and Slack and didn't find a solution to my problem.
  • I have searched the GitHub issue tracker and didn't find a similar bug report.
  • I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions