Vue i18n pro moderní aplikace
Podpora rozhraní Composition API a Options API s bezproblémovou integrací Nuxt.
Connect Vue to Better i18n in four steps
No Vue-specific package to install — the zero-dependency core client feeds vue-i18n directly.
Install the client and vue-i18n
There is no Vue-specific SDK to add — @better-i18n/core is framework-agnostic and vue-i18n stays your formatter.
npm install @better-i18n/core vue-i18n
# @better-i18n/core ships zero dependencies —
# it is the same client our React SDKs are built on.Create the Better i18n client once
Instantiate at module scope: the TTL cache lives on the instance, so a per-component client would refetch on every mount.
import { createI18nCore } from '@better-i18n/core'
export const betterI18n = createI18nCore({
projectId: 'your-org/your-project', // Settings → General → Project ID
defaultLocale: 'en',
})Boot vue-i18n with CDN messages
Fetch the active locale before mounting and hand the object straight to createI18n — the shape vue-i18n expects is the shape the CDN returns.
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
import App from './App.vue'
import { betterI18n } from './lib/better-i18n'
const locale = 'en'
// Messages come from the Better i18n CDN, cached in-memory for 60s.
const messages = await betterI18n.getMessages(locale)
const i18n = createI18n({
legacy: false, // Composition API
locale,
fallbackLocale: 'en',
messages: { [locale]: messages },
})
createApp(App).use(i18n).mount('#app')Switch locale at runtime
Load the target locale on demand and register it with setLocaleMessage, so a user only ever downloads the languages they actually open.
import { useI18n } from 'vue-i18n'
import { betterI18n } from './lib/better-i18n'
const { locale, setLocaleMessage } = useI18n()
// Locales are discovered from the project manifest — no hardcoded list.
const languages = await betterI18n.getLanguages()
async function switchTo(next: string) {
setLocaleMessage(next, await betterI18n.getMessages(next))
locale.value = next
}How it works
Where a Vue string comes from
No build step and no bundled JSON: the client resolves a locale at runtime, the edge answers it, and R2 is the source of truth behind both.
Read path — every locale load
useI18n() reads the message vue-i18n already holds.
0 network calls per render
getMessages(locale) — served from the in-memory cache if it is warm.
60s TTL · 0 deps
Cloudflare worker answers from the nearest edge cache.
max-age=60 · always 200
The published translation files the sync worker wrote.
source of truth
Fallback chain — tried in order when a hop fails
Write path — dashboard to app
Proposal reviewed in the dashboard, glossary enforced.
MCP · dashboard · CLI
Sync worker writes the locale files to R2.
better-i18n publish
Fire-and-forget purge of the affected keys and the manifest.
non-critical by design
The next getMessages() past the TTL returns the new copy.
~60s worst case
Rychlý start
Přidejte i18n do své aplikace Vue pomocí rozhraní API Composition.
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
const { t, d, n } = useI18n()
</script>
<template>
<section>
<h1>{{ t('home.title') }}</h1>
<p>{{ t('home.greeting', { name: 'World' }) }}</p>
<!-- ICU plurals authored in the Better i18n dashboard -->
<p>{{ t('cart.items', { count: 3 }) }}</p>
<!-- vue-i18n formatters, locale-aware -->
<time>{{ d(new Date(), 'short') }}</time>
<span>{{ n(1299.9, 'currency') }}</span>
</section>
</template>Funkce
Everything below is shipped behaviour of @better-i18n/core, the CDN and the dashboard.
Better I18N and the Vue ecosystem
We handle translation management and delivery; the Vue libraries you already use keep their jobs.
Better I18N + vue-i18n
The official Vue plugin, maintained by the Vue team. Handles t(), plurals, date and number formatting, and reactive locale state.Better i18n replaces the local JSON files it reads, nothing else changes
Better I18N + Nuxt
@nuxtjs/i18n owns routing, prefixes and SEO tags; translation delivery is the part it leaves to you.Call the same client from a Nuxt plugin — it runs server-side and on the client
Better I18N + Vue Router
Path-prefixed locales (/tr/urunler) need the locale resolved before the route renders.core exports extractLocale, addLocalePrefix and replaceLocaleInPath for that
Související
Vue i18n — Frequently Asked Questions
Is there a @better-i18n/vue package?
No, and you do not need one. @better-i18n/core ships with zero dependencies and is the same client our React SDKs are built on, so you call createI18nCore() directly and pass the messages to vue-i18n. A thin Vue wrapper would only save you the four lines in the setup guide above. If you want one anyway, say so on GitHub — that demand is what would prioritise it.
What is the best i18n library for Vue.js?
vue-i18n is the official internationalization plugin for Vue, maintained by the Vue core team. It supports Vue 2 and Vue 3, the Composition API, and integrates with Nuxt via @nuxtjs/i18n. It formats and renders strings; it does not manage, translate or deliver them. Better I18N covers that half — AI translation with glossary enforcement, review workflow, and CDN delivery — and hands vue-i18n the finished messages.
How does this work with the Composition API?
Exactly as vue-i18n normally does: create the plugin with legacy set to false, then call useI18n() inside script setup to get t(), d() and n(). Locale state stays reactive, so assigning locale.value re-renders every component that reads a translated string. Better I18N only changes where the messages come from — getMessages(locale) from the CDN instead of an imported JSON file.
Can the CLI extract keys from .vue files?
Not yet. The scanner's default extensions are .tsx, .jsx, .ts and .js, so better-i18n scan and better-i18n sync will walk past your SFCs today. Until that lands, manage Vue keys through the dashboard, the MCP server, or better-i18n keys create — and note that keys defined in plain .ts composables ARE picked up. Everything else in the CLI (publish, translations, languages, publish:status) is API-driven and framework-independent.
Does it work with Nuxt and server-side rendering?
Yes. The client has no browser-only dependencies, so calling getMessages() from a Nuxt plugin or server route works the same as in the browser, and the fetched object can be serialised into the SSR payload to avoid a second request on the client. Instantiate the client at module scope so the 60-second TTL cache is shared across requests rather than rebuilt per render.
How do plurals and ICU messages survive the trip?
ICU is preserved end-to-end: a message authored as {count, plural, one {# item} other {# items}} in the dashboard reaches vue-i18n as that exact string, and vue-i18n resolves it at render time. The dashboard also shows translators the correct plural categories for each target language, so a Turkish or Polish translator is not guessing which forms exist.
What happens when the CDN request fails?
The client walks a five-layer fallback chain: in-memory TTL cache, CDN fetch with timeout and retry, persistent storage if you configured one, then staticData, and only then does it throw. The CDN itself always answers HTTP 200 — on an internal error it returns an empty object rather than a 5xx — so a translation outage degrades to stale or fallback copy instead of a blank page.
How fast are published changes visible in a Vue app?
Publishing writes to R2 and fires a CDN purge, and the CDN sets max-age=60 on translations. With the client's own 60-second TTL cache in front of that, a published string is live in roughly a minute at worst — no redeploy, no bundle rebuild. Call getMessages with forceRefresh through getManifest if you need to bypass it during QA.
Prohlédněte si další průvodce po frameworku
Get started
Začněte stavět s Vue i18n
K dispozici je bezplatná úroveň. Není vyžadována kreditní karta.