intlify/vue-i18n

`useI18n` does not work in web component when using Vue 3.5's `configureApp` option

Opened this issue · 0 comments

Reporting a bug?

Vue 3.5 added a new way of passing plugins to Vue web components: https://blog.vuejs.org/posts/vue-3-5#custom-elements-improvements

const i18n = createI18n({
  locale: 'en',
  messages: {
    en: {
      foo: 'translated foo',
      bar: 'translated bar',
    },
  },
});

const ce = defineCustomElement(VueCustomElement, {
  configureApp(app) {
    app.use(i18n);
  },
});

Unfortunately using useI18n() does not work inside the web component.

Uncaught SyntaxError: Need to install with `provide` function
    createCompileError vue-i18n.js:235
    createI18nError vue-i18n.js:3457
    getI18nInstance vue-i18n.js:5154
    useI18n vue-i18n.js:5106
    setup VueCustomElement.ce.vue:12

However, it does work inside a normal vue component that is used by the vue web component.

Expected behavior

When vue-i18n is registered using configureApp, useI18n should work with vue web components and normal vue components.

Reproduction

Minimal reproduction on stackblitz: https://stackblitz.com/edit/vitejs-vite-egcpgj?file=src%2Fcomponents%2FVueCustomElement.ce.vue

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.20.3 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.15.6 - /usr/local/bin/pnpm
  npmPackages:
    @vitejs/plugin-vue: ^5.2.0 => 5.2.0 
    vite: ^5.4.11 => 5.4.11 
    vue: ^3.5.12 => 3.5.12 
    vue-i18n: ^10.0.4 => 10.0.4

Screenshot

No response

Additional context

I think this is caused by this part:

function getI18nInstance(instance: ComponentInternalInstance): I18n {
const i18n = inject(
!instance.isCE
? instance.appContext.app.__VUE_I18N_SYMBOL__!
: I18nInjectionKey
)
/* istanbul ignore if */
if (!i18n) {
throw createI18nError(
!instance.isCE
? I18nErrorCodes.UNEXPECTED_ERROR
: I18nErrorCodes.NOT_INSTALLED_WITH_PROVIDE
)
}
return i18n
}

If an instance is a WebComponent/CustomElement it tries to inject it using I18nInjectionKey. But because i18n was registered using configureApp, it is available on instance.appContext.app.__VUE_I18N_SYMBOL__!, not I18nInjectionKey.

Validations