Building a multilingual website is essential for reaching global audiences. Nuxt.js, combined with the official @nuxtjs/i18n module, provides a powerful solution for creating internationally-aware web applications that deliver seamless language switching, SEO-friendly URLs, and maintainable translation workflows.
In this guide, we'll walk through the complete process of implementing internationalization in your Nuxt.js projects, from initial setup to advanced features like dynamic content integration. Our web development team specializes in building scalable, multilingual applications that serve audiences across North America, Europe, and beyond.
As highlighted by Smashing Magazine's comprehensive Nuxt i18n tutorial, proper internationalization implementation significantly improves user engagement across markets. The official Nuxt i18n documentation provides the technical foundation for all the patterns we'll explore.
What makes @nuxtjs/i18n the go-to solution for Nuxt.js internationalization
Route Localization
Automatic URL-based language routing with SEO-friendly prefixes and domain support
Lazy Loading
On-demand translation file loading to optimize initial page load performance
Browser Detection
Automatic detection of user language preferences with configurable fallbacks
SEO Optimization
Built-in hreflang tag generation and locale-specific meta tags
Getting Started: Installing and Configuring Nuxt i18N
Installation
The @nuxtjs/i18n module is the official internationalization solution for Nuxt.js. Install it using the Nuxt CLI:
npx nuxi@latest module add i18n
Or install it manually:
npm install @nuxtjs/i18n
Basic Configuration
Add the module to your nuxt.config.ts and configure your locales:
export default defineNuxtConfig({
modules: ['@nuxtjs/i18n'],
i18n: {
locales: [
{ code: 'en', name: 'English', file: 'en.json' },
{ code: 'fr', name: 'Français', file: 'fr.json' },
{ code: 'es', name: 'Español', file: 'es.json' }
],
defaultLocale: 'en',
lazy: true,
langDir: 'locales',
strategy: 'prefix_except_default'
}
})
Following the approach recommended by LogRocket's Nuxt 3 i18n guide, this configuration provides a solid foundation for multilingual applications.
Managing Translation Files
Lazy Loading for Performance
For production applications with extensive translations, enable lazy loading to fetch language files only when needed:
// nuxt.config.ts
i18n: {
lazy: true,
langDir: 'locales',
loadPath: '/locales/{{lng}}.json'
}
Translation File Structure
Organize your translation files with clear, hierarchical keys:
// locales/en.json
{
"common": {
"home": "Home",
"about": "About",
"contact": "Contact Us"
},
"homePage": {
"title": "Welcome to Our Website",
"subtitle": "Discover amazing content"
}
}
Using Translations in Components
Access translations using the useI18n composable:
<script setup>
const { t } = useI18n()
</script>
<template>
<h1>{{ t('homePage.title') }}</h1>
<p>{{ t('homePage.subtitle') }}</p>
</template>
As documented in the Vue I18n documentation, this composable provides access to all internationalization features including interpolation, pluralization, and formatting.
Building Language Switchers
Locale Switcher Component
Create a language selector that switches between locales while maintaining the current page:
<script setup>
const { locale, locales } = useI18n()
const switchLocalePath = useSwitchLocalePath()
</script>
<template>
<select v-model="locale" @change="navigateTo(switchLocalePath($event.target.value))">
<option v-for="l in locales" :key="l.code" :value="l.code">
{{ l.name }}
</option>
</select>
</template>
Browser Language Detection
Nuxt i18n automatically detects the user's browser language preference and redirects accordingly. Configure fallback behavior:
i18n: {
detectBrowserLanguage: {
useCookie: true,
cookieKey: 'i18n_redirected',
redirectOn: 'root',
alwaysRedirect: true
}
}
For optimal user experience, combine browser detection with explicit language switching to allow users to override the automatic selection. This approach, recommended by Smashing Magazine, balances convenience with user control.
Localized Routing for SEO
URL Structure Options
Nuxt i18n supports multiple routing strategies:
| Strategy | Example URLs | Best For |
|---|---|---|
| prefix | /en/about, /fr/a-propos | Consistent URL structure |
| prefix_except_default | /about, /fr/a-propos | Clean URLs for default language |
| no_prefix | Different domains | Maximum URL simplicity |
Domain-Based Routing
For production sites requiring different domains per language:
i18n: {
locales: [
{ code: 'en', domain: 'example.com' },
{ code: 'fr', domain: 'example.fr' },
{ code: 'es', domain: 'example.es' }
]
}
SEO Benefits
Nuxt i18n automatically generates hreflang tags for all locales, ensuring search engines serve the correct language version to users:
<link rel="alternate" hreflang="en" href="https://example.com/en/about" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/a-propos" />
<link rel="alternate" hreflang="es" href="https://example.com/es/acerca-de" />
This automated hreflang generation, as explained in the LogRocket i18n guide, is essential for international SEO success and helps avoid duplicate content issues. When implementing multilingual sites for your AI-powered applications, proper SEO configuration ensures your global audience can find your content in their preferred language.
Advanced Features: Interpolation and Formatting
Dynamic Content Insertion
Use placeholders for dynamic content in translations:
// en.json
{
"welcome": "Welcome, {name}!",
"itemsCount": "You have {count} items"
}
// Component usage
{{ t('welcome', { name: userName }) }}
{{ t('itemsCount', { count: itemCount }) }}
Pluralization
Handle language-specific plural rules automatically:
// en.json
{
"items": {
"one": "{count} item",
"other": "{count} items"
}
}
// fr.json (has 'few' rule)
{
"items": {
"one": "{count} élément",
"few": "{count} éléments",
"many": "{count} éléments"
}
}
Date and Number Formatting
Use the built-in Intl API for locale-aware formatting:
const { d, n } = useI18n()
// Date formatting
d(new Date(), 'long')
// Number formatting
n(price, 'currency')
The Vue I18n documentation covers these advanced formatting capabilities in detail, including support for complex pluralization rules in languages like Arabic and Russian.
Integrating Dynamic Content from Headless CMS
Many modern applications fetch localized content from headless CMS platforms. Here's how to integrate them with Nuxt i18n:
Querying Localized Content
const query = gql`
query GetPost($slug: String!, $locale: Locale!) {
post(where: { slug: $slug }) {
title
content
locale
}
}
`
const { data } = await useAsyncData('post', () =>
client.request(query, {
slug: route.params.slug,
locale: locale.value
})
)
Best Practices
- Always pass the current locale to your CMS queries
- Cache localized content at the CDN level
- Implement fallback content for missing translations
- Use SSR for initial load, client-side navigation for subsequent pages
The Hygraph Nuxt i18n example repository demonstrates production-ready patterns for headless CMS integration with multilingual content. This approach ensures your web development projects can scale to support any number of markets efficiently.
Best Practices for Production
Performance Optimization
- Enable lazy loading for translation files
- Use CDN caching for locale files
- Implement route preloading for common languages
- Monitor Core Web Vitals across all locales
Translation Management
- Use dedicated translation management platforms (Crowdin, Lokalise, Phrase)
- Implement review workflows before publishing translations
- Separate translation concerns from code repositories
- Version control translation files alongside code
Accessibility
- Ensure language switchers are keyboard accessible
- Use proper
langattributes on the HTML element - Test with screen readers across all supported languages
- Consider RTL (right-to-left) language support
Testing
- Implement end-to-end tests for each locale
- Visual regression testing across languages
- Test language switching during user flows
- Verify SEO tags are correctly generated
By following these production best practices, your multilingual implementation will be scalable, maintainable, and performant across all supported languages.