Skip to content

i18n / Localization

Status: Audit v0.1 (2026-05-09).

1. Status

The web client has no internationalisation infrastructure.

Tool Wired? Source
vue-i18n No Not in package.json
@nuxtjs/i18n No Same
react-intl, lingui, i18next No Same
Translation files (JSON / YAML) No No locales/ or translations/ directory
Translation management system No No Lokalise / Crowdin / Transifex config

grep -rE "vue-i18n\|@nuxtjs/i18n" package.json polotno-editor/package.json returns no matches.

All UI strings are hardcoded English in .vue template blocks and JS string literals.

2. Backend-supplied locale data

The backend does provide a /getLanguages endpoint (cached via api/fetchLanguages in store/api.js). This returns a list of languages — likely for content language selection (the user's posts can be in different languages), not for UI locale.

grep -nE "getLanguages\|languagesCache" store middleware 2>/dev/null confirms it's about post content, not UI.

[VERIFY-I18N-1]: confirm with the team that /getLanguages is content-language only, not UI-translation.

3. Tone of voice

Similar — getToneOfVoice returns content-tone presets ("formal", "casual", etc.) for AI generation, not UI locale.

4. Date / number / currency formatting

Concern Status
Dates moment + moment-timezone are used heavily; moment(...).format('...') calls are English-formatted by default. moment.locale(...) could switch but there are no observed moment.locale calls.
Numbers helpers/helper.js → formatMetrics and commaSeparatedNumber use n.toLocaleString() for the small case but hard-coded K/M/B/T suffixes (English). Other locales would need Intl.NumberFormat with compactDisplay.
Currency Stripe / Paddle handle their own currency formatting in their UI widgets. The web client itself has no currency-formatting helper observed.

Finding [WC-I18N-1] (Severity: Medium): Number / date formatting is locale-naive. Even without UI translation, formatting numbers as 1,234,567.89 (US) for a German user is wrong (1.234.567,89). Pure-Intl adoption is feasible without full i18n.

5. RTL languages

No RTL CSS support observed:

grep -rE "\[dir=\"rtl\"\]\|direction:\s*rtl" assets pages components 2>/dev/null
# (likely empty — verify)

Adding Arabic / Hebrew support would require:

  1. RTL stylesheet (bootstrap-rtl or BS5's rtl build).
  2. Logical CSS properties (margin-inline-start instead of margin-left) — currently using BS4-era mr-2/ml-2 classes which are not RTL-aware.
  3. A direction-switcher tied to locale.

This is a Phase 2+ effort if internationalisation is on the roadmap.

6. Implications for enterprise customers

Enterprise B2B customers — especially those in Europe, the Middle East, or APAC — frequently require:

  • At minimum: locale-aware date/number formatting.
  • Often: UI translation for the languages of their users.
  • Sometimes: contractually mandated WCAG + locale support.

The current state means the web client cannot be sold "as-is" to a non-English-first market. Verify with the team whether the product strategy targets non-English markets in the next 12 months.

7. Recommendations

Phase 1 (if internationalisation is on the roadmap)

  1. Adopt vue-i18n@8 (Vue 2 compatible) or @nuxtjs/i18n@7.
  2. Sweep all UI strings into locales/en.json. This is the bulk effort — likely 1–2 weeks for the 159K LOC, given the level of inline strings.
  3. Connect to a TMS (Lokalise or Crowdin).
  4. Add Intl.NumberFormat / Intl.DateTimeFormat helpers to helpers/helper.js; deprecate moment's English-locked formatting.

Phase 2

  • Add second locale (likely Spanish or French based on customer geography — verify).
  • RTL support if Arabic/Hebrew are targeted.

Phase 3

  • Continue rollout to more locales as customer demand materialises.

8. Open questions

Tracked in ./verify-markers.md:

  • [VERIFY-I18N-1] Confirm /getLanguages is content-language only
  • [VERIFY-I18N-2] Is internationalisation on the product roadmap?