| name | i18n |
| description | Bilingual EN/ES system (useI18n, localePath, locale files). Use when adding UI strings, localized routes, or keys in app/locales/*.json. |
Internationalization (i18n)
Bilingual EN/ES system with @nuxtjs/i18n v10. Strategy prefix_except_default.
Key files
app/locales/en.json - English translations (base language)
app/locales/es.json - Spanish translations
nuxt.config.ts - configuration (i18n: section)
Route strategy
- English (default, no prefix):
/, /about, /projects, /blog, /blog/[slug]
- Spanish (with
/es prefix): /es/, /es/about, /es/projects, /es/blog, /es/blog/[slug]
Composables (auto-imported)
const { t, tm, rt, locale, setLocale } = useI18n()
const localePath = useLocalePath()
const switchLocalePath = useSwitchLocalePath()
Key functions
t('navigation.items.home')
t('blog.post.author')
const raw = tm('hero.techStack')
const items = raw.map(item => ({ name: rt(item.name) }))
locale.value
setLocale('es')
localePath('/about')
localePath('/blog/my-article')
localePath({ name: 'blog-slug', params: { slug: 'my-slug' } })
switchLocalePath('es')
Key structure in locales
navigation.* - menu, brand, toggles, social links
errors.* - error messages and actions
seo.* - site SEO, defaults, pages
blog.* - blog section texts (eyebrow, title, post.*, toc.*, pagination.*, nav.*)
footer.* - footer
hero.* - landing page hero
overview.* - overview cards on the landing
about.* - about page
projects.* - projects page
resources.* - resources page
loader.* - loading messages
useAsyncData with i18n pattern
const { locale } = useI18n()
const { getPosts } = useBlog()
const { data: posts } = await useAsyncData(
() => `blog-index-${locale.value}`,
() => getPosts(),
{ watch: [locale] }
)
Localized navigation
<!-- Template -->
<NuxtLink :to="localePath('/blog')">Blog</NuxtLink>
<NuxtLink :to="localePath(`/blog/${post.slug}`)">{{ post.title }}</NuxtLink>
navigateTo(localePath('/about'))
Restrictions
- Never hard-code UI strings; always use
t()
tm() returns AST (not strings); use rt() to resolve each element
- Add keys in both files (en.json and es.json) simultaneously
- Do not use
$router.push('/path') without localePath()
- Language change:
setLocale() + appStore.setLanguage() (see the app-store skill)