GitHub Action · vue-i18n · Vue 3 + Options API

i18n coverage for vue-i18n

The Lokali GitHub Action detects vue-i18n's flat locales/*.json and src/locales/*.json layouts, distinguishes the vue-i18n plugin from the core vue framework package, and flags every $t() / t() call that falls through to a missing key — including pluralization forms and lazy-loaded locale chunks.

locales/*.json, src/locales/*.json
Scan your Vue repo → Install the GitHub App

What the Action checks for vue-i18n

Lokali reads your package.json first to separate vue-i18n (the plugin) from vue (the framework), then scans the same flat layouts your createI18n({ messages }) call expects.

DETECT — vue vs vue-i18n packages
Reads package.json deps and counts vue-i18n separately so framework UI strings don't pollute the translation baseline.
DETECT — flat locales/
Flat locales/{lang}.json and src/locales/{lang}.json one-file-per-locale layouts used by Vue 3's createI18n composable out of the box.
DETECT — vue.component locale registration
Respects app.use(i18n) and any i18n.global.mergeLocaleMessage() / i18n.component('MyComp', ...) registration that introduces extra locales at runtime.
DETECT — $t usage against missing keys
Cross-references every $t('namespace.key') / t('namespace.key') call (when in the diff) against the locale file and flags keys that resolve to the key itself at runtime.
DETECT — pluralization forms
Counts the full CLDR plural set per key — zero, one, two, few, many, other — across all locales so missing ru.few or ar.dual forms show up per locale, not as a flat missing key.
DETECT — fallback chains + lazy chunks
Honors i18n.loadLocaleAsync() / dynamic import() lazy chunks per locale and reads fallbackLocale chains so a fallback doesn't silently mask a real missing translation.

Common coverage gaps the Action flags

These three failure modes hit real vue-i18n apps — each one lands in the comment as a per-locale missing-keys row you can act on before the PR merges.


Sample Action report on a vue-i18n PR

What lokali[bot] posts in the PR thread after a push touches src/locales/en.json. The same table is dropped into the first-run Coverage delta PR.

lokali[bot] commented · i18n Coverage Report
## i18n Coverage Report · vue-i18n

Baseline: `src/locales/en.json` · 142 keys · locales: 7
Package detected: `vue-i18n@9.x` (separated from `vue@3.x`)

| Locale   | Coverage | Total | Translated | Missing |
|----------|----------|-------|------------|---------|
| 🟢 en    |   100%   |  142  |    142     |    0    |
| 🟢 de    |    97%   |  142  |    138     |    4    |
| 🟡 fr    |    93%   |  142  |    132     |   10    |
| 🟡 es    |    90%   |  142  |    128     |   14    |
| 🟡 pt-BR |    84%   |  142  |    119     |   23    |
| 🔴 ja    |    61%   |  142  |     87     |   55    |
| 🔴 ru    |    34%   |  142  |     48     |   94    |

CLDR pluralization forms missing per locale:
  • `cart.items` → en has 2 forms (other/keyed), ru has only `other` → missing `one`, `few`, `many`
  • `billing.invoices` → de has `one`/`other`, ar has only `other` → missing `zero`, `two`, `few`, `many`

Lazy chunk registration missing:
  • `src/locales/ko.json` exists but no `i18n.loadLocaleAsync('ko')` call

Fallback chain warning:
  • `pt-BR` (via fallbackLocale) appears 100% at runtime — Action reports real 84%; gap is `cart.total`, `cart.discount`

Coverage delta PR opened: #1234 — `lokali: coverage-delta-2026-08-16`

Scan a vue-i18n repo or install the Action

One URL works for both. Coverage comments arrive on your next PR, and the Coverage delta PR closes the gap automatically — across pluralization forms, fallback chains, and lazy-loaded locale chunks.

Run a free i18n audit → ← Back to integrations hub