Back to all docs
BeMyWords with Vue
Integration guide for Vue 3 applications using vue-i18n.
Shape of the integration:
- At build time, fetch translations from BeMyWords into JSON resource files.
- Configure
vue-i18nto load them at app init. - Use
$t()/useI18n()in components.
Prerequisites
- A Vue 3 project (Vite-based assumed).
vue-i18ninstalled:npm install vue-i18n@latest.- A BeMyWords workspace, project, namespace, API key.
1. Environment variables
.env.local:
BEMYWORDS_BASE_URL=https://www.bemywords.no
BEMYWORDS_PROJECT_ID=<your-project-uuid>
BEMYWORDS_API_TOKEN=<your-api-token>
BEMYWORDS_NAMESPACE=app
Do not prefix BEMYWORDS_API_TOKEN with VITE_ — it must stay server-side.
2. Fetch script
scripts/fetch-translations.mjs:
import { writeFileSync, mkdirSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const OUTPUT_DIR = join(__dirname, "..", "src", "locales");
const BASE_URL = process.env.BEMYWORDS_BASE_URL || "https://www.bemywords.no";
const PROJECT_ID = process.env.BEMYWORDS_PROJECT_ID;
const API_TOKEN = process.env.BEMYWORDS_API_TOKEN;
const NAMESPACE = process.env.BEMYWORDS_NAMESPACE || "app";
const LANGUAGES = ["en", "nb"];
async function fetchLanguage(lang) {
const url = `${BASE_URL}/api/${PROJECT_ID}/latest/${lang}/${NAMESPACE}`;
const res = await fetch(url, { headers: { Authorization: `Token token=${API_TOKEN}` } });
if (!res.ok) throw new Error(`${lang}: HTTP ${res.status}`);
return res.json();
}
async function main() {
mkdirSync(OUTPUT_DIR, { recursive: true });
if (!PROJECT_ID || !API_TOKEN) {
console.warn("BEMYWORDS_* env vars not set.");
return;
}
for (const lang of LANGUAGES) {
const data = await fetchLanguage(lang);
writeFileSync(join(OUTPUT_DIR, `${lang}.json`), JSON.stringify(data, null, 2) + "\n");
}
}
main().catch((e) => { console.error(e); process.exit(1); });
3. Configure vue-i18n
src/i18n.ts:
import { createI18n } from "vue-i18n";
import en from "./locales/en.json";
import nb from "./locales/nb.json";
export default createI18n({
legacy: false, // Composition API mode
locale: "en",
fallbackLocale: "en",
messages: { en, nb },
});
src/main.ts:
import { createApp } from "vue";
import App from "./App.vue";
import i18n from "./i18n";
createApp(App).use(i18n).mount("#app");
4. Use in components
Composition API:
<script setup>
import { useI18n } from "vue-i18n";
const { t } = useI18n();
</script>
<template>
<h1>{{ t("home.hero.title") }}</h1>
<p>{{ t("home.hero.subtitle") }}</p>
</template>
Options API / templates-only:
<template>
<h1>{{ $t("home.hero.title") }}</h1>
</template>
BeMyWords returns flat dot-keys. vue-i18n reads dot notation natively — no conversion needed.
5. Hook into build
package.json:
{
"scripts": {
"predev": "node scripts/fetch-translations.mjs",
"prebuild": "node scripts/fetch-translations.mjs",
"dev": "vite",
"build": "vite build"
}
}
Pluralization and interpolation
vue-i18n uses pipe-separated plurals and {name} interpolation:
{
"apples": "no apples | 1 apple | {count} apples",
"greeting": "Hello, {name}!"
}
Store these strings verbatim in BeMyWords. Enable placeholder validation in project settings.
API reference
Status
This guide is a best-effort draft — not yet verified in a production Vue deployment. Please test before relying on it and report corrections.