Skip to content

Add internationalisation (i18n) support to the platform UI #8359

Description

@hmjvalineY

Description

Problem

The FlowFuse platform UI is English-only and has no i18n infrastructure. On main at v3.0.0 (56b076e7), frontend/src/i18n.js, frontend/src/locales/ and a root locales/ directory do not exist, and there is no i18n or polyglot dependency in package.json.

Approximate translatable string counts across 542 .vue files (79,189 lines): ~1,049 bare template text nodes, ~358 label/title/placeholder/header attribute strings, ~155 Alerts.emit messages, plus 19 email templates in forge/postoffice/templates/.

There is also an inconsistency that non-English-speaking self-hosted teams hit immediately. Node-RED already ships 10 editor locales (de, en-US, es-ES, fr, ja, ko, pt-BR, ru, zh-CN, zh-TW), and because nr-launcher does not set lang in the generated settings.js, Node-RED falls back to the browser locale. So a user with a Chinese browser locale gets a fully localised Node-RED editor embedded inside an entirely English platform shell.

Motivation

I run a self-hosted FlowFuse deployment for a Traditional Chinese (zh-TW) speaking team, and localising the platform shell is the remaining gap. I would rather contribute this upstream than maintain a private fork, so the work starts from the shared infrastructure and the en baseline rather than from my own locale.

Reference

I reviewed PR #5692 and the docs/contribute/i18n.md contributor guide on its feature/i18n-implementation branch, and followed the architecture defined there — the library choices, the locale directory layout, and the hierarchical key-naming convention.

The implementation is written fresh against main rather than rebased from that branch, which is now ~4,700 commits behind and pins fastify-i18n@^1 (Fastify 4 era) and vue-i18n@^9.

Implementation

  • Frontendvue-i18n@^11, config at frontend/src/i18n.js, locales at frontend/src/locales/<locale>.json
  • Backendfastify-i18n@^3 over node-polyglot, locales at locales/<locale>/common.json. The two interpolation syntaxes differ ({name} vs %{name}); that is documented rather than papered over.
  • Both webpack entrypoints — the plugin is registered on setup.js as well as main.js, so the first-run setup flow is translated too
  • Locale resolution — stored User.language, then the request or browser locale, then en. The login and sign-up pages render before there is a session, so browser detection is what makes them translatable at all.
  • User.language — a new nullable column, so this carries a DB migration and needs the area:migration label

One correction to what I wrote in #8311: I said fastify-i18n@3 normalises Accept-Language and that browser detection would need no custom code on the backend. That is only half true. It narrows a regional tag onto its base language (en-GB finds en) but does not widen a script-qualified tag onto a regional one, so zh-Hant-TW fell back to English rather than finding zh-TW — and Chrome reports exactly that tag for Traditional Chinese on some platforms. A LOCALE_ALIASES map in forge/i18n/locales.js handles it, and a test covers it. I had assumed the library did this; a test proved otherwise.

Status

Implemented and open as #8312 — 5 commits, 422 files, 2,879 locale keys with en and zh-TW in step.

Full build and test results are in the PR description: lint clean against the pre-change baseline, 3,346 forge unit tests, 886 frontend, 61 system, the migration verified on SQLite, and manual verification in both locales including the pre-session pages.

The PR grew well beyond the initial page set proposed here, because the infrastructure on its own left a signed-in user reading English on every page — setting a language preference did not visibly do anything. The PR offers to split that: the plumbing and the en extraction separately from the zh-TW values, whichever is easier to review.

Re-filed through this template because I originally opened #8311 as a blank issue, so it never picked up the needs-triage label and has been sitting outside the triage queue rather than waiting in it. Closing #8311 in favour of this one.

One small thing noticed while doing that: .github/ISSUE_TEMPLATE/03-feature.yml declares labels: [needs-triage, feature-request], but there is no feature-request label in this repository — the nearest existing ones are type:feature, customer request and sales request. GitHub drops a template label that does not exist, silently, so every issue filed through that template gets only needs-triage. This one included. Either creating the label or pointing the template at type:feature would fix it.

Which customers would this be available to

Everyone - CE/Starter/Team/Enterprise

Have you provided an initial effort estimate for this issue?

I am not a FlowFuse team member

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageNeeds looking at to decide what to do

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions