@groupteknology/nuxt-i18n
v0.0.6
Published
Lightweight typed i18n module for Nuxt
Downloads
438
Maintainers
Readme
@groupteknology/nuxt-i18n
A small Nuxt i18n module focused on typed translations, simple setup, and SSR-safe locale persistence.
It is a good fit when you want:
- typed translation keys from your default locale
- typed interpolation params from message placeholders
- cookie-based locale persistence that works on SSR and client
- a minimal
useI18n()API without routing, SEO, or domain strategies
Features
- messages from local TypeScript files
- nested key lookup like
page.home.title t(path, params?)with inferred params from{name}and{{name}}locale,locales, andsetLocale(code)fromuseI18n()- fallback to
fallbackLocalewhen a key is missing - optional locale detection from
Accept-Languageandnavigator.language - configurable cookie options
onMissing(path, locale, fallbackLocale)for custom fallback text- generated types for locale codes, translation paths, and params
Install
pnpm add @groupteknology/nuxt-i18nQuick Setup
Register the module in nuxt.config.ts:
export default defineNuxtConfig({
modules: ['@groupteknology/nuxt-i18n'],
i18n: {
defaultLocale: 'es',
fallbackLocale: 'es',
dir: 'i18n',
detectLocale: true,
warnOnMissing: true,
cookie: {
name: 'locale',
sameSite: 'lax',
},
locales: [
{ code: 'es', file: 'es.ts', name: 'Español' },
{ code: 'en', file: 'en.ts', name: 'English' },
],
onMissing: (path, locale) => `[missing:${locale}] ${path}`,
},
})Create your locale files in i18n/locales:
// i18n/locales/es.ts
import { defineI18nLocale } from '@groupteknology/nuxt-i18n'
export default defineI18nLocale({
form: {
placeholder: {
name: 'Tu nombre es {{name}}',
},
},
page: {
home: {
description: 'Esta es la página de inicio',
title: 'Página de inicio',
},
},
})// i18n/locales/en.ts
import type { LocaleInput } from '@groupteknology/nuxt-i18n'
export default {
form: {
placeholder: {
name: 'Your name is {{name}}',
},
},
page: {
home: {
description: 'This is the home page',
title: 'Home page',
},
},
} satisfies LocaleInputUse it in components:
<script setup lang="ts">
const { locale, locales, setLocale, t } = useI18n()
</script>
<template>
<div>
<h1>{{ t('page.home.title') }}</h1>
<p>{{ t('page.home.description') }}</p>
<p>{{ t('form.placeholder.name', { name: 'Diego' }) }}</p>
<button v-for="item in locales" :key="item.code" @click="setLocale(item.code)">
{{ item.name }}
</button>
<pre>{{ locale }}</pre>
</div>
</template>Typed Messages
The default locale is the source of truth for generated translation types.
- translation paths are inferred from the default locale object
- interpolation params are inferred from placeholders like
{{name}} - secondary locales can be partial by using
satisfies LocaleInput
defineI18nLocale() helps preserve literal strings so TypeScript can infer params correctly. For example:
t('form.placeholder.name', { name: 'Ada' })This is valid, while missing or misspelled params are caught by TypeScript.
Locale Resolution
The active locale is resolved in this order:
- cookie value
- detected locale, if
detectLocale: true defaultLocale
When detection is enabled, the module checks:
Accept-Languageduring SSRnavigator.languagesandnavigator.languageon the client
If a translation is missing in the active locale, the module tries fallbackLocale. If the key is still missing, onMissing() can return a custom string before warnOnMissing logs a warning.
API
useI18n() returns:
locale: current locale reflocales: configured locale listsetLocale(code): change the active localet(path, params?): translate a message
The plugin also injects:
$locale$locales$setLocale$t
Options
type NuxtI18nOptions = {
cookie?: {
maxAge?: number
name?: string
sameSite?: 'lax' | 'none' | 'strict'
secure?: boolean
}
defaultLocale?: string
detectLocale?: boolean
dir?: string
fallbackLocale?: string
locales?: Array<{
code: string
file: `${string}.ts`
name: string
}>
onMissing?: (path: string, locale: string, fallbackLocale: string) => string | undefined
warnOnMissing?: boolean
}Scope
This module intentionally stays small.
Included:
- typed local messages
- cookie persistence
- SSR/client locale detection
- fallback locale support
- missing-key customization
Not included:
- localized routing
- SEO tags or
hreflang - domain-based locale strategies
- advanced message formatting or ICU syntax
Local Development
npm install
npm run dev:prepare
npm run devUseful commands:
npm run dev:buildnpm run lintnpm run prepacknpm run release
Maintainer Docs
For internal project context:
