Skip to content

feat: decouple component library from vue-i18n#1186

Draft
Arnold Stoba (arnoldstoba) wants to merge 2 commits into
mainfrom
feat/decouple-vue-i18n
Draft

feat: decouple component library from vue-i18n#1186
Arnold Stoba (arnoldstoba) wants to merge 2 commits into
mainfrom
feat/decouple-vue-i18n

Conversation

@arnoldstoba

@arnoldstoba Arnold Stoba (arnoldstoba) commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Closes #1070

What?

Make the component library translation-solution agnostic: it no longer depends on vue-i18n. Components use an internal i18n layer with an optional host adapter, bundled EN/DE snippets, a reactive locale, and predictable fallbacks. Hosts and plugins can now override Meteor snippets and add languages.

⚠️ Breaking change → ships as a major (6.0.0).

Why?

Meteor declared vue-i18n@^9 as a hard dependency. This forced a specific library and version on every consumer. Apps on a newer vue-i18n (e.g. the Admin on v10, a Nuxt app on @nuxtjs/i18n) ended up with two vue-i18n instances — Meteor's useI18n() resolved a different instance than the host's, breaking translations.

We chose an internal layer + adapter (over simply bumping vue-i18n) because it removes the forced dependency entirely and is the only way to be truly version- and library-agnostic. It also unlocks snippet overriding/extension, which the old per-component local scope did not allow.

How?

  • Removed vue-i18n from dependencies and the build externals (nothing in the bundle imports it anymore).
  • Added useMeteorI18n + createMeteorI18nPlugin({ adapter?, messages? }) (source under src/i18n/). Resolution order: host adapter → override registry → bundled locale → bundled English → key, with a locale fallback chain (de-DE → de → en, en-US → en).
  • Snippets now have public keys mt.<component>.<key> so hosts/plugins can target them.
  • Shipped createVueI18nAdapter (accepts a createI18n instance or a composer, so it also works with @nuxtjs/i18n).
  • Migrated all 34 translated components; updated tests, Storybook (EN/DE toggle), README, developer docs, and the example apps.

Testing?

  • Unit tests cover the resolution order, locale chain, pluralization, and overrides (655 passing).
  • lint:all, lint:types, and the production build all pass; the bundle contains 0 vue-i18n imports.
  • A separate manual verification guide exists for validating the Admin integration end-to-end before bumping shopware/shopware.

Anything Else?

Consumer migration

Zero setup now works — components render bundled English out of the box and no longer throw without vue-i18n:

- npm i @shopware-ag/meteor-component-library vue-i18n
+ npm i @shopware-ag/meteor-component-library

To drive the locale reactively / let your app provide translations, install the plugin:

// already using vue-i18n (or @nuxtjs/i18n):
import { createMeteorI18nPlugin, createVueI18nAdapter } from "@shopware-ag/meteor-component-library";
app.use(i18n);
app.use(createMeteorI18nPlugin({ adapter: createVueI18nAdapter(i18n) }));

// or, standalone with bundled snippets only:
app.use(createMeteorI18nPlugin());

Override wording / add a language (host-first, or via the registry):

app.use(createMeteorI18nPlugin({
  messages: { fr: { mt: { pagination: { nextPage: "Suivant" } } } },
}));

💥 Breaking changes

  1. vue-i18n is no longer a dependency. Meteor no longer installs it for you; if your app uses it, declare it yourself.
  2. Translations are no longer auto-wired from a shared vue-i18n instance. To get non-English / reactive locale in Meteor components you must install createMeteorI18nPlugin (with an adapter). Without it, Meteor renders English instead of throwing.
  3. Snippet keys for the previously global-scoped components were renamed (mt-mt.): mt-field-error.* → mt.field-error.*, mt-text-editor*.* → mt.text-editor*.*, mt-action-menu-item.* → mt.action-menu-item.*. Plugins overriding these must update the key path. The Admin's global.error-codes.* keys are unchanged.

@vercel

vercel Bot commented Jun 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
meteor-component-library Ready Ready Preview, Comment Jun 29, 2026 1:13pm

Request Review

Make the component library translation-solution agnostic. Components now use an
internal i18n layer (useMeteorI18n + createMeteorI18nPlugin) with an optional host
adapter, bundled English/German snippets, a reactive locale, and predictable
fallbacks: host adapter -> override registry -> bundled locale -> bundled English -> key.

- Remove the hard vue-i18n dependency and externalization (resolves the version
  conflict from #1070; nothing in the bundle imports vue-i18n anymore)
- Public snippet keys are namespaced mt.<component>.<key>
- Hosts/plugins can override snippets and add languages, seamlessly: host-first in
  the Admin (translate mt.* like any admin snippet) or via createMeteorI18nPlugin({ messages })
- Locale fallback chain (de-DE -> de -> en, en-US -> en); region variants share the
  language default, region-specific overrides win
- createVueI18nAdapter helper accepts a createI18n instance or a composer (@nuxtjs/i18n)
- Migrate 34 components; the mt-text-editor cluster shares one catalog
- Update tests, Storybook (en/de locale toggle), README, developer docs, and example apps

The create-meteor-extension scaffold keeps the published-compatible setup; it will be
updated to the new i18n API once 6.0.0 is published (its CI test installs from the registry).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a Playwright test that exercises the full chain in a real consumer app
(createMeteorI18nPlugin + createVueI18nAdapter + reactive host locale):

- bundled EN snippets by default, switch to bundled DE on locale change
- region variants share the language default (en-US -> en)
- a region-specific override (en-GB -> mt.pagination.infoText) wins for en-GB only
- non-overridden keys still fall back to bundled en even at en-GB
- the en-GB override does not leak to en-US / en

The demo surface is gated behind ?i18n=1 so the default page (and the existing
smoke-test screenshot) is unchanged. Runs in the existing "Playwright Integration
Tests" CI job.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update version of vue/i18n

1 participant