Nuxt 3 i18n Configuration and Best Practices Guide
This guide provides Nuxt 3 internationalization configuration and best practices, implementing multilingual support via @nuxtjs/i18n. It explains i18n's importance for expanding user base, enhancing experience, boosting brand image, and SEO, covering prerequisites (Node.js 16+, Nuxt 3.12.4+) and dependency installation to build global web apps.

Nuxt 3 Internationalization Complete Guide: From Configuration to Best Practices
In the era of globalization, providing multilingual support for your web applications has become a key factor in enhancing user experience and expanding your audience reach. As a powerful Vue framework, Nuxt.js offers a comprehensive internationalization solution through the @nuxtjs/i18n module. This article will detail how to configure and optimize internationalization features in Nuxt 3 projects, helping you easily build modern multilingual web applications.
Why Internationalization?
Before diving into configuration, let's understand the importance of internationalization (i18n):
- Expand User Base: Supporting multiple languages allows your application to reach a wider global audience
- Enhance User Experience: Users prefer interfaces in their native language, significantly improving satisfaction and retention
- Strengthen Brand Image: Multilingual support demonstrates a global vision and respect for cultural diversity
- SEO Advantages: Content optimized for different languages and regions tends to rank better in local search engines
Preparation
Environment Requirements
Before starting, ensure your development environment meets these requirements:
- Node.js 16.x or higher
- Nuxt.js 3.12.4 or higher
- npm or yarn package manager
Installing Dependencies
First, install the @nuxtjs/i18n module in your Nuxt 3 project:
bash
npm install @nuxtjs/i18n
## or using yarn
yarn add @nuxtjs/i18n
This article is based on @nuxtjs/i18n@10.0.6, the latest stable version at the time of writing.
Project Structure Preparation
The recommended directory structure for internationalization files is as follows:
project/
├── i18n/
│ └── locales/ # Store all language translation files
│ ├── zh-CN.json # Simplified Chinese translations
│ └── en-US.json # American English translations
└── nuxt.config.ts # Nuxt configuration file
This structure clearly separates internationalization-related files for easier maintenance and expansion.
Core Configuration
Basic Configuration
First, add the i18n module to nuxt.config.ts and perform basic configuration:
typescript
export default defineNuxtConfig({
// Import i18n module
modules: [
'@nuxtjs/i18n'
],
// i18n module configuration
i18n: {
// Define supported languages
locales: [
{
code: 'zh-CN', // Language code, used for URL prefix
name: '中文', // Language name, can be used for UI display
file: 'zh-CN.json', // Corresponding translation file
iso: 'zh-CN' // ISO language code for hreflang and other SEO tags
},
{
code: 'en-US',
name: 'English',
file: 'en-US.json',
iso: 'en-US'
}
],
// Directory for translation files
langDir: 'i18n/locales/',
// Default language
defaultLocale: 'zh-CN',
// Routing strategy
strategy: 'prefix_except_default',
// Browser language detection configuration
detectBrowserLanguage: {
useCookie: true, // Use cookie to remember user language preference
cookieKey: 'i18n_redirected', // Cookie key name
redirectOn: 'root', // Redirect only when accessing root path
alwaysRedirect: false, // Redirect only on first visit
cookieSecure: false // Set to false in development, true in production recommended
},
// SEO optimization
seo: true, // Automatically generate hreflang tags
// Debug mode, recommended to enable during development
debug: process.env.NODE_ENV === 'development'
}
})
This basic configuration already meets the internationalization needs of most projects, but let's dive deeper into the role and principles behind each configuration item.
Routing Strategy Details
@nuxtjs/i18n provides three routing strategies, each suitable for different scenarios:
| Strategy | Description | Advantages | Disadvantages |
|---|---|---|---|
no_prefix |
No URL prefix for any language | Keeps URLs clean | Not SEO-friendly, difficult to distinguish between language versions |
prefix_except_default |
No prefix for default language, prefix for others | SEO-friendly, balanced URL cleanliness | Slightly more complex implementation |
prefix |
Prefix for all languages | Simple implementation, good consistency | Default language URL has unnecessary prefix |
Recommended: prefix_except_default strategy for the following reasons:
- SEO Optimization: Different language versions have different URLs, making it easier for search engines to index them separately
- User Experience: Default language users see clean URLs, while others clearly know their language version
- Cache Optimization: Different URLs for different language versions prevent browser cache confusion
- Direct Access: Users can directly access specific language versions via URL
Translation File Configuration
Translation files use JSON format. It's recommended to organize translation content with nested structures to make translation keys more semantic.
Chinese Translation File (zh-CN.json)
json
{
"nav": {
"home": "首页",
"about": "关于我们",
"services": "服务",
"contact": "联系我们"
},
"home": {
"welcome": "欢迎来到我们的网站",
"description": "这是一个使用Nuxt 3和@nuxtjs/i18n构建的多语言网站示例",
"features": "核心特性"
},
"common": {
"learn_more": "了解更多",
"submit": "提交",
"cancel": "取消"
}
}
English Translation File (en-US.json)
json
{
"nav": {
"home": "Home",
"about": "About Us",
"services": "Services",
"contact": "Contact Us"
},
"home": {
"welcome": "Welcome to Our Website",
"description": "This is a multilingual website example built with Nuxt 3 and @nuxtjs/i18n",
"features": "Core Features"
},
"common": {
"learn_more": "Learn More",
"submit": "Submit",
"cancel": "Cancel"
}
}
Best Practices for Translation Files:
- Use consistent nested structures for easier maintenance
- Use semantic naming, avoiding meaningless keys like "text1" or "btn2"
- Keep key structures consistent across all language files
- Consider using translation management tools (e.g., i18next, vue-i18n-extract) for managing translations in large projects
Using Internationalization in Components
Basic Text Translation
@nuxtjs/i18n provides multiple ways to use translations in components. The most common are the $t function (in templates) and the useI18n composable API (in scripts).
vue
<template>
<div class="home-page">
<!-- Use $t function directly in template -->
<h1>{{ $t('home.welcome') }}</h1>
<p>{{ $t('home.description') }}</p>
<!-- Translation with parameters -->
<p>{{ $t('common.greeting', { name: 'Visitor' }) }}</p>
</div>
</template>
<script setup>
// Use composable API in script
const { t, locale, setLocale } = useI18n()
// Get current language
console.log('Current language:', locale.value) // Output: zh-CN or en-US
// Get translated text in script
const featuresTitle = t('home.features')
</script>
Translations with Parameters
For translation texts that need dynamic content insertion, you can use parameterized translations:
First, define text with placeholders in the translation file:
json
// zh-CN.json
{
"common": {
"greeting": "欢迎,{name}!",
"notification": "您有 {count} 条新消息"
}
}
Then use it in components:
vue
<!-- Using in template -->
<p>{{ $t('common.greeting', { name: userName }) }}</p>
<p>{{ $t('common.notification', { count: unreadCount }) }}</p>
<!-- Using in script -->
<script setup>
const { t } = useI18n()
const userName = '用户'
const userGreeting = t('common.greeting', { name: userName })
</script>
Language Switcher Component
Create a language switcher component to allow users to manually switch languages:
vue
<!-- components/LanguageSwitcher.vue -->
<template>
<div class="language-switcher">
<button
v-for="lang in availableLocales"
:key="lang.code"
:class="{ active: lang.code === currentLocale }"
@click="switchLanguage(lang.code)"
>
{{ lang.name }}
</button>
</div>
</template>
<script setup>
const { locale, setLocale, getAvailableLocales } = useI18n()
// Get current language
const currentLocale = locale
// Get all available languages
const availableLocales = getAvailableLocales()
// Switch language
const switchLanguage = async (langCode) => {
// You can add loading state here
await setLocale(langCode)
// Operations after language switch, such as scrolling to top
window.scrollTo(0, 0)
}
</script>
<style scoped>
.language-switcher {
display: flex;
gap: 0.5rem;
}
button {
padding: 0.25rem 0.75rem;
border: 1px solid #e5e7eb;
border-radius: 4px;
background: white;
cursor: pointer;
}
button.active {
background: #3b82f6;
color: white;
border-color: #3b82f6;
}
</style>
This component displays all available languages and highlights the currently selected language. When a button is clicked, it calls the setLocale method to switch languages.
Internationalized Routing
@nuxtjs/i18n automatically generates internationalized routes for your pages. For pages in the pages directory:
pages/
├── index.vue # Home page
├── about.vue # About page
└── contact.vue # Contact page
The module will automatically generate the following routes:
- Default language (zh-CN):
/,/about,/contact - Other languages (en-US):
/en-US,/en-US/about,/en-US/contact
When using the <NuxtLink> component in templates, you can specify the language version of the link via the locale property:
vue
<!-- Link to about page in current language -->
<NuxtLink to="/about">
{{ $t('nav.about') }}
</NuxtLink>
<!-- Link to about page in specific language (English) -->
<NuxtLink to="/about" :locale="en-US">
English About Page
</NuxtLink>
<!-- Generate internationalized links in script -->
<script setup>
const { localePath } = useI18n()
// Generate about page link for current language
const aboutUrl = localePath('/about')
// Generate contact page link for specific language
const enContactUrl = localePath('/contact', { locale: 'en-US' })
</script>
Common Issues and Solutions
1. "input.replace is not a function" Error
Problem Description: When using @nuxtjs/i18n v10.x, you may encounter a path resolution error with the message "input.replace is not a function".
Root Cause: This is typically due to significant changes in the configuration approach for Vue I18n in version 10, making older configuration methods incompatible with the new version.
Solutions:
- Remove any
vueI18nconfiguration blocks that may exist innuxt.config.ts - Ensure the
langDirpath correctly points to the translation file directory - There's no need to create a separate
i18n.config.tsfile; all configurations should be placed in thei18noption innuxt.config.ts
2. Content Not Updating After Language Switch
Problem Description: After clicking the language switch button, the URL may update, but the page content doesn't switch to the newly selected language.
Possible Causes and Solutions:
-
Translation Key Mismatch
- Check if the corresponding key exists in translation files
- Ensure key structures are consistent across all language files
-
Routing Strategy Configuration Issue
- Avoid using the
no_prefixstrategy, especially in development environments - Recommended to use
prefix_except_defaultstrategy for easier debugging
- Avoid using the
-
Component Caching Issue
- If using
<NuxtPage>or<Suspense>, you may need to force a refresh - Try executing
window.location.reload()after switching languages (not recommended, only as a temporary solution)
- If using
-
langDir Path Error
- Check if the
langDirconfiguration correctly points to the translation file directory relative to the project root - Ensure translation files exist and have valid JSON format
- Check if the
3. TypeScript Type Errors
Problem Description: TypeScript reports errors about not finding defineI18nConfig or related types.
Solutions:
- Ensure
@nuxtjs/i18nversion is compatible with Nuxt 3 version - Delete any independent
i18n.config.tsfile; it's no longer needed in v10 - Place all configurations directly in the
i18noption ofnuxt.config.ts - Install the latest type definitions:
npm install --save-dev @types/node @types/vue-i18n
4. Browser Language Detection Not Working
Problem Description: When accessing the website, browser language detection doesn't redirect to the user's preferred language as expected.
Solutions:
- Check
detectBrowserLanguageconfiguration, ensureuseCookieis set totrue - Clear browser cookies and try again (previous incorrect settings may be cached)
- Ensure
redirectOnis set correctly, with'root'meaning redirect only on root path access - In development environment, set
debugtotrueto view language detection logs in the console
Best Practices and Performance Optimization
1. Translation File Organization
-
Divide by Feature Modules: For large projects, split translation files by feature modules instead of having one file per language
locales/ ├── zh-CN/ │ ├── common.json │ ├── home.json │ └── user.json └── en-US/ ├── common.json ├── home.json └── user.json -
Use Standard Language Codes: Follow ISO 639-1 language codes and ISO 3166-1 country codes, such as
zh-CN,en-US,fr-FR -
Keep Translation Files in Sync: Use tools like i18n-ally (VS Code extension) to help manage translations and ensure consistent key structures across all language files
2. Performance Optimization
-
Enable Lazy Loading: Configure
lazy: trueto load translation files on demand and reduce initial loading timetypescripti18n: { lazy: true, // Enable lazy loading langDir: 'i18n/locales/', // Other configurations... } -
Configure Language Detection Appropriately: Avoid excessive detection by setting
redirectOn: 'root'to redirect only on root path -
Use Cookies to Remember Preferences: Set
useCookie: trueto avoid language detection and redirection on every visit
3. SEO Optimization
SEO for international websites requires special attention to ensure different language versions are properly indexed:
-
Use the Right Routing Strategy:
prefix_except_defaultorprefixstrategies are more SEO-friendly -
Automatically Generate hreflang Tags: Enable the
seo: trueconfiguration, and the module will automatically generate hreflang tags for different language versions -
Set Language Meta Tags: Configure dynamic language attributes in
app.headtypescript// nuxt.config.ts export default defineNuxtConfig({ app: { head: { htmlAttrs: { lang: 'zh-CN' // Defaults to default language } } } }) -
Create Sitemaps for Each Language: Use the
nuxt-sitemapmodule to generate separate sitemaps for different language versions
4. Development Workflow Optimization
-
Hot Reload Support:
@nuxtjs/i18nsupports hot reloading of translation files, so you don't need to restart the development server after modifying translations -
Use VS Code Extensions: Recommended to use the i18n-ally extension, which provides translation key autocompletion, real-time previews, and batch operation capabilities
-
Translation Management Tool Integration: For large projects or multi-team collaboration, consider integrating professional translation management tools like Lokalise, Crowdin, or POEditor
### Nuxt 3 Internationalization Complete Guide: From Configuration to Best Practices
In the era of globalization, providing multilingual support for your web applications has become a key factor in enhancing user experience and expanding your audience reach. As a powerful Vue framework, Nuxt