Skip to content

feat: support useI18n({ messages }) in locale message extraction#695

Draft
jariz wants to merge 1 commit into
intlify:masterfrom
jariz-forks:feat/use-i18n-no-missing-keys
Draft

feat: support useI18n({ messages }) in locale message extraction#695
jariz wants to merge 1 commit into
intlify:masterfrom
jariz-forks:feat/use-i18n-no-missing-keys

Conversation

@jariz
Copy link
Copy Markdown

@jariz jariz commented Feb 10, 2026

In short, adds supports for useI18n({ messages }).
Read more in the full issue: #694

What's supported

  • Inline object literals: useI18n({ messages: { en: { ... }, ja: { ... } } })
  • Local variable references: const msgs = { ... }; useI18n({ messages: msgs })
  • Default imports: import messages from './messages.json'; useI18n({ messages })
  • Named imports: import { messages } from './i18n.js'; useI18n({ messages })
  • Aliased named imports: import { messages as msgs } from './i18n.js'; useI18n({ messages: msgs })
  • TypeScript as expressions: useI18n({ messages: { ... } as const })
  • Multiple useI18n() calls in a single file (each produces its own locale message set)
  • Combined sources: <i18n> blocks + useI18n({ messages }) + localeDir all merge together
  • Nested keys: t('form.submit') resolves correctly against nested message objects
  • String, number, boolean, null literal values and static template literals (no expressions)

What's NOT supported (silently skipped)

  • Spread elements: useI18n({ messages: { ...base, en: { ... } } }) — the entire messages object is skipped if any spread is encountered since it's not statically analyzable
  • Computed property keys: useI18n({ messages: { [locale]: { ... } } }) — skipped
  • Dynamic values: useI18n({ messages: getMessages() }) or any non-identifier, non-object expression — skipped
  • Namespace imports: import * as msgs from '...' — not resolved
  • Non-top-level variable declarations: only top-level const/let/var in the module scope are collected (sufficient for <script setup>)
  • Re-exports / indirect references: const a = b; useI18n({ messages: a }) where b is another variable — only one level of indirection is followed
  • Template literals with expressions: `${dynamicLocale}` as values — skipped
  • Non-existent import paths: if the resolved file doesn't exist on disk, silently skipped

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Feb 10, 2026

⚠️ No Changeset found

Latest commit: 3c08384

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

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.

1 participant