How can I configure Nuxt.js to achieve URL patterns with language postfixes for internationalization? I want to use routes like /foo for the default language and /foo/kz for the Kazakh version, but my current configuration isn’t working. What’s the proper way to set up Nuxt-i18n for this pattern?
Configuring Nuxt.js to achieve URL patterns with language postfixes requires using the custom routes feature of the @nuxtjs/i18n module instead of the default prefix strategy. With proper configuration, you can set up routes like /foo for your default language (English) and /foo/kz for Kazakh, creating clean, intuitive URLs that don’t include locale prefixes for the default language but still support language-specific postfixes.
Contents
- Understanding Default Nuxt i18n Behavior
- Custom Routes Configuration Options
- Module-Level Custom Routes Setup
- Page-Level Custom Routes Setup
- Complete Configuration Example
- Troubleshooting Common Issues
- Best Practices for Language Postfix URLs
- Alternative Solutions
Understanding Default Nuxt i18n Behavior
By default, Nuxt i18n uses a route locale strategy called “prefix_except_default,” which adds locale prefixes to every URL except for the default language. The official Nuxt i18n documentation explains that “Nuxt i18n module overrides Nuxt default routes to add locale prefixes to every URL (except in ‘no_prefix’ strategy).” This means if you have English as your default language and Kazakh as a secondary language, you would typically get URLs like /foo for English and /kz/foo for Kazakh.
However, this default behavior isn’t what you’re looking for when you want language postfixes like /foo/kz. According to the official custom paths guide, “Nuxt i18n lets you translate URLs, but the default strategy (prefix_except_default) prefixes the locale code. If you need post-fixed language codes (e.g. /foo → default, /foo/kz → Kazakh) you must use custom routes.”
Custom Routes Configuration Options
The Nuxt i18n module provides two primary methods for defining custom routes: module-level configuration in your nuxt.config.ts file or page-level configuration using definePageMeta() or defineI18nRoute(). As the official documentation states, “There are two ways to define custom routes: customRoutes: ‘config’ (module-level in nuxt.config.ts) or customRoutes: ‘page’ (page-level using definePageMeta() or defineI18nRoute()).”
Each approach has its advantages:
- Module-level: Centralized management of all custom routes
- Page-level: More granular control closer to the actual page components
For achieving language postfixes, both methods will work, but the module-level approach is often simpler for consistent URL patterns across your application.
Module-Level Custom Routes Setup
To configure module-level custom routes for your language postfix pattern, you’ll need to modify your nuxt.config.ts file. The key is to specify the customRoutes option as ‘config’ and then define your routes without locale prefixes in the pages configuration.
Here’s how to set it up:
- First, ensure your
i18nconfiguration includes thecustomRoutesoption set to ‘config’:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxtjs/i18n'],
i18n: {
strategy: 'prefix_except_default',
customRoutes: 'config',
// ... other i18n configurations
}
})
- Then, define your custom routes in the
pagessection of your configuration. The official documentation provides a clear pattern: “In pages, map the route name to the desired paths without locale prefixes: pages: { foo: { en: ‘/foo’, kz: ‘/foo/kz’ } }”
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxtjs/i18n'],
i18n: {
strategy: 'prefix_except_default',
customRoutes: 'config',
locales: [
{ code: 'en', iso: 'en-US', name: 'English' },
{ code: 'kz', iso: 'kk-KZ', name: 'Kazakh' }
],
defaultLocale: 'en',
// Define custom routes for language postfixes
customRoutes: {
foo: {
en: '/foo',
kz: '/foo/kz'
}
// Add more routes as needed
}
}
})
The key point emphasized by the official documentation is: “Ensure the default locale is set to en so /foo is served without a prefix.” This configuration will give you exactly what you want: /foo serving English content and /foo/kz serving Kazakh content.
Page-Level Custom Routes Setup
If you prefer to configure custom routes at the page level, you can use the defineI18nRoute function in your page components. This approach gives you more granular control over individual page routing.
Here’s how to implement page-level custom routes:
- First, ensure your
i18nconfiguration is set up with the custom routes strategy:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxtjs/i18n'],
i18n: {
strategy: 'prefix_except_default',
customRoutes: 'page',
// ... other i18n configurations
}
})
- Then, in your page component, define the custom route:
<script setup>
defineI18nRoute({
paths: {
en: '/foo',
kz: '/foo/kz'
}
})
</script>
<template>
<!-- Your page content -->
</template>
The page-level approach allows you to override routing behavior for specific pages while maintaining the default behavior for others. This can be particularly useful when you only need language postfixes for certain routes rather than your entire application.
Complete Configuration Example
Here’s a complete working example that demonstrates how to achieve the desired URL patterns with language postfixes:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxtjs/i18n'],
i18n: {
// Use custom routes for language postfixes
strategy: 'prefix_except_default',
customRoutes: 'config',
// Define supported locales
locales: [
{
code: 'en',
iso: 'en-US',
name: 'English',
file: 'en.json'
},
{
code: 'kz',
iso: 'kk-KZ',
name: 'Kazakh',
file: 'kz.json'
}
],
// Set English as default locale
defaultLocale: 'en',
// Define custom routes with language postfixes
customRoutes: {
// Home page
index: {
en: '/',
kz: '/kz'
},
// About page
about: {
en: '/about',
kz: '/about/kz'
},
// Product page with dynamic route
'products-product': {
en: '/products/:id',
kz: '/products/:id/kz'
},
// Your example route
foo: {
en: '/foo',
kz: '/foo/kz'
}
},
// Additional i18n configurations
detectBrowserLanguage: {
useCookie: true,
cookieKey: 'i18n_redirected',
redirectOn: 'root' // Only redirect on root path
},
langDir: 'locales/',
defaultDirection: 'ltr',
vueI18n: {
legacy: false,
fallbackLocale: 'en'
}
}
})
This configuration sets up a complete internationalization solution with language postfixes. Each route is defined separately for each locale, allowing you to precisely control the URL structure as described in the official Nuxt i18n documentation.
Troubleshooting Common Issues
When implementing language postfix routes in Nuxt.js, you might encounter several common issues. Here’s how to address them:
1. Routes Not Working as Expected
If your custom routes aren’t producing the expected URLs, double-check that your customRoutes configuration is properly structured. The official documentation emphasizes that “Nuxt i18n lets you translate URLs, but the default strategy (prefix_except_default) prefixes the locale code. If you need post-fixed language codes (e.g. /foo → default, /foo/kz → Kazakh) you must use custom routes.”
2. Dynamic Routes with Language Postfixes
For dynamic routes like /products/:id and /products/:id/kz, ensure you’re properly defining the route name in your page file:
<!-- pages/products/[id].vue -->
<script setup>
defineI18nRoute({
paths: {
en: '/products/:id',
kz: '/products/:id/kz'
}
})
</script>
3. Navigation Between Languages
When linking between different language versions of a page, use Nuxt’s localePath function:
<script setup>
const { localePath } = useI18n()
// Link to English version
const englishLink = localePath({ name: 'foo' }, 'en')
// Link to Kazakh version
const kazakhLink = localePath({ name: 'foo' }, 'kz')
</script>
<template>
<NuxtLink :to="englishLink">English Version</NuxtLink>
<NuxtLink :to="kazakhLink">Kazakh Version</NuxtLink>
</template>
4. SEO Considerations
According to Phrase’s Nuxt i18n guide, “By default, Nuxt I18n uses a route locale ‘prefix except default’ strategy i.e. /foo has en-CA content, /ar-EG/foo has ar-EG content.” When implementing language postfixes, ensure you’ve properly configured your sitemap and hreflang tags to maintain good SEO practices.
Best Practices for Language Postfix URLs
When implementing language postfix URLs in your Nuxt.js application, consider these best practices:
-
Consistency: Maintain consistent URL patterns across your entire application for better user experience and SEO.
-
Readability: Ensure your language postfixes are intuitive. Using
/foo/kzis clearer than/foo-kzas it visually separates the language code from the actual path. -
Navigation: Provide clear language switchers that help users understand how to navigate between different language versions.
-
Browser Language Detection: Configure the
detectBrowserLanguageoption to automatically redirect users to their preferred language version:
// nuxt.config.ts
i18n: {
detectBrowserLanguage: {
useCookie: true,
cookieKey: 'i18n_redirected',
redirectOn: 'root',
fallbackLocale: 'en'
}
}
-
Fallback Handling: Always provide a fallback to your default language when content isn’t available in the requested language.
-
Testing: Thoroughly test your routing behavior, especially with edge cases like empty routes, nested routes, and dynamic parameters.
-
Performance: Monitor the performance impact of your custom routing configuration, especially as your application grows in complexity.
Alternative Solutions
While custom routes with language postfixes are the recommended approach for your specific requirement, there are other routing strategies you might consider depending on your needs:
1. No Prefix Strategy
If you don’t want any language indicators in your URLs, you could use the “no_prefix” strategy:
// nuxt.config.ts
i18n: {
strategy: 'no_prefix',
// Other configurations
}
However, this approach makes it difficult for search engines to identify different language versions of your content.
2. Different Domains per Language
For larger applications, you might consider using different domains for each language:
// nuxt.config.ts
i18n: {
strategy: 'no_prefix',
differentDomains: true,
domains: [
{
domain: 'example.com',
locales: ['en']
},
{
domain: 'example.kz',
locales: ['kz']
}
]
}
3. Path Prefix Strategy
If you prefer traditional path prefixes like /en/foo and /kz/foo, you could use the default “prefix_except_default” strategy without custom routes.
Conclusion
Configuring Nuxt.js to achieve URL patterns with language postfixes requires leveraging the custom routes feature of the @nuxtjs/i18n module. By setting customRoutes: 'config' in your nuxt.config.ts and defining your routes with specific paths for each locale, you can create clean, intuitive URLs like /foo for your default language and /foo/kz for Kazakh. The official Nuxt i18n documentation provides clear guidance on implementing this pattern, emphasizing that “if you need post-fixed language codes (e.g. /foo → default, /foo/kz → Kazakh) you must use custom routes.” This approach ensures your internationalized application has URLs that are both user-friendly and SEO-optimized.