How to Build a Multilingual Website with Nuxt i18N

A comprehensive guide to implementing internationalization in Nuxt.js applications using @nuxtjs/i18n, covering setup, routing, translations, and SEO optimization.

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.

Key Features of Nuxt i18N

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:

StrategyExample URLsBest For
prefix/en/about, /fr/a-proposConsistent URL structure
prefix_except_default/about, /fr/a-proposClean URLs for default language
no_prefixDifferent domainsMaximum 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 lang attributes 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.

Frequently Asked Questions

Ready to Build Your Multilingual Website?

Our expert Nuxt.js developers can help you implement internationalization and create seamless multilingual experiences for your global audience.