\n\n\n```\n\nThe 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.\n\n## Complete Configuration Example {#complete-example}\n\nHere's a complete working example that demonstrates how to achieve the desired URL patterns with language postfixes:\n\n```typescript\n// nuxt.config.ts\nexport default defineNuxtConfig({\n modules: ['@nuxtjs/i18n'],\n \n i18n: {\n // Use custom routes for language postfixes\n strategy: 'prefix_except_default',\n customRoutes: 'config',\n \n // Define supported locales\n locales: [\n { \n code: 'en', \n iso: 'en-US', \n name: 'English',\n file: 'en.json'\n },\n { \n code: 'kz', \n iso: 'kk-KZ', \n name: 'Kazakh',\n file: 'kz.json'\n }\n ],\n \n // Set English as default locale\n defaultLocale: 'en',\n \n // Define custom routes with language postfixes\n customRoutes: {\n // Home page\n index: {\n en: '/',\n kz: '/kz'\n },\n \n // About page\n about: {\n en: '/about',\n kz: '/about/kz'\n },\n \n // Product page with dynamic route\n 'products-product': {\n en: '/products/:id',\n kz: '/products/:id/kz'\n },\n \n // Your example route\n foo: {\n en: '/foo',\n kz: '/foo/kz'\n }\n },\n \n // Additional i18n configurations\n detectBrowserLanguage: {\n useCookie: true,\n cookieKey: 'i18n_redirected',\n redirectOn: 'root' // Only redirect on root path\n },\n \n langDir: 'locales/',\n defaultDirection: 'ltr',\n vueI18n: {\n legacy: false,\n fallbackLocale: 'en'\n }\n }\n})\n```\n\nThis 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](https://i18n.nuxtjs.org/docs/guide/custom-paths).\n\n## Troubleshooting Common Issues {#troubleshooting}\n\nWhen implementing language postfix routes in Nuxt.js, you might encounter several common issues. Here's how to address them:\n\n### 1. Routes Not Working as Expected\n\nIf your custom routes aren't producing the expected URLs, double-check that your `customRoutes` configuration is properly structured. The [official documentation](https://i18n.nuxtjs.org/docs/guide/custom-paths) 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*.\"\n\n### 2. Dynamic Routes with Language Postfixes\n\nFor dynamic routes like `/products/:id` and `/products/:id/kz`, ensure you're properly defining the route name in your page file:\n\n```vue\n\n\n```\n\n### 3. Navigation Between Languages\n\nWhen linking between different language versions of a page, use Nuxt's `localePath` function:\n\n```vue\n\n\n\n```\n\n### 4. SEO Considerations\n\nAccording to [Phrase's Nuxt i18n guide](https://phrase.com/blog/posts/nuxt-js-tutorial-i18n/), \"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.\n\n## Best Practices for Language Postfix URLs {#best-practices}\n\nWhen implementing language postfix URLs in your Nuxt.js application, consider these best practices:\n\n1. **Consistency**: Maintain consistent URL patterns across your entire application for better user experience and SEO.\n\n2. **Readability**: Ensure your language postfixes are intuitive. Using `/foo/kz` is clearer than `/foo-kz` as it visually separates the language code from the actual path.\n\n3. **Navigation**: Provide clear language switchers that help users understand how to navigate between different language versions.\n\n4. **Browser Language Detection**: Configure the `detectBrowserLanguage` option to automatically redirect users to their preferred language version:\n\n```typescript\n// nuxt.config.ts\ni18n: {\n detectBrowserLanguage: {\n useCookie: true,\n cookieKey: 'i18n_redirected',\n redirectOn: 'root',\n fallbackLocale: 'en'\n }\n}\n```\n\n5. **Fallback Handling**: Always provide a fallback to your default language when content isn't available in the requested language.\n\n6. **Testing**: Thoroughly test your routing behavior, especially with edge cases like empty routes, nested routes, and dynamic parameters.\n\n7. **Performance**: Monitor the performance impact of your custom routing configuration, especially as your application grows in complexity.\n\n## Alternative Solutions {#alternative-solutions}\n\nWhile 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:\n\n### 1. No Prefix Strategy\n\nIf you don't want any language indicators in your URLs, you could use the \"no_prefix\" strategy:\n\n```typescript\n// nuxt.config.ts\ni18n: {\n strategy: 'no_prefix',\n // Other configurations\n}\n```\n\nHowever, this approach makes it difficult for search engines to identify different language versions of your content.\n\n### 2. Different Domains per Language\n\nFor larger applications, you might consider using different domains for each language:\n\n```typescript\n// nuxt.config.ts\ni18n: {\n strategy: 'no_prefix',\n differentDomains: true,\n domains: [\n {\n domain: 'example.com',\n locales: ['en']\n },\n {\n domain: 'example.kz',\n locales: ['kz']\n }\n ]\n}\n```\n\n### 3. Path Prefix Strategy\n\nIf you prefer traditional path prefixes like `/en/foo` and `/kz/foo`, you could use the default \"prefix_except_default\" strategy without custom routes.\n\n## Conclusion {#conclusion}\n\nConfiguring 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](https://i18n.nuxtjs.org/docs/guide/custom-paths) 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.\n\n## Sources {#sources}\n\n- [Routing Strategies - @nuxtjs/i18n](https://i18n.nuxtjs.org/docs/guide)\n- [Custom Route Paths - @nuxtjs/i18n](https://i18n.nuxtjs.org/docs/guide/custom-paths)\n- [The Complete Guide to Nuxt Localization](https://phrase.com/blog/posts/nuxt-js-tutorial-i18n/)\n- [Nuxt i18n: Translate your Nuxt.js app into multiple languages](https://lokalise.com/blog/nuxt-i18n-translate-your-nuxt-js-app-into-multiple-languages/)\n- [Guide to Configuring i18n in Nuxt 3 with Vue 3](https://medium.com/@nagarjun_nagesh/guide-to-configuring-i18n-in-nuxt-3-with-vue-3-cbe9978328df)"},{"name":"How to Configure Nuxt.js i18n for Language Postfix URLs","step":[{"name":"Understanding Default Nuxt i18n Behavior","@type":"HowToStep","@id":"https://neuroanswers.net/c/web/q/nuxt-js-i18n-language-postfix-urls-custom-routes","position":1},{"name":"Custom Routes Configuration Options","@type":"HowToStep","@id":"https://neuroanswers.net/c/web/q/nuxt-js-i18n-language-postfix-urls-custom-routes","position":2},{"name":"Module-Level Custom Routes Setup","@type":"HowToStep","@id":"https://neuroanswers.net/c/web/q/nuxt-js-i18n-language-postfix-urls-custom-routes","position":3},{"name":"Page-Level Custom Routes Setup","@type":"HowToStep","@id":"https://neuroanswers.net/c/web/q/nuxt-js-i18n-language-postfix-urls-custom-routes","position":4},{"name":"Complete Configuration Example","@type":"HowToStep","@id":"https://neuroanswers.net/c/web/q/nuxt-js-i18n-language-postfix-urls-custom-routes","position":5},{"name":"Troubleshooting Common Issues","@type":"HowToStep","@id":"https://neuroanswers.net/c/web/q/nuxt-js-i18n-language-postfix-urls-custom-routes","position":6},{"name":"Best Practices for Language Postfix URLs","@type":"HowToStep","@id":"https://neuroanswers.net/c/web/q/nuxt-js-i18n-language-postfix-urls-custom-routes","position":7},{"name":"Alternative Solutions","@type":"HowToStep","@id":"https://neuroanswers.net/c/web/q/nuxt-js-i18n-language-postfix-urls-custom-routes","position":8}],"@type":"HowTo","@context":"https://schema.org","description":"Step-by-step guide to setting up Nuxt.js i18n to achieve URL patterns with language postfixes like /foo for default and /foo/kz for Kazakh, using custom routes.","mainEntityOfPage":{"@type":"WebPage","@id":"https://neuroanswers.net/c/web/q/nuxt-js-i18n-language-postfix-urls-custom-routes"},"inLanguage":"en","dateCreated":"2025-12-23T10:33:06.600Z","datePublished":"2025-12-23T10:33:06.600Z","dateModified":"2025-12-23T10:33:06.600Z","author":[{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}}],"publisher":{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}},"@id":"https://neuroanswers.net/c/web/q/nuxt-js-i18n-language-postfix-urls-custom-routes","url":"https://neuroanswers.net/c/web/q/nuxt-js-i18n-language-postfix-urls-custom-routes"},{"@type":"CollectionPage","@id":"https://neuroanswers.net/c/web/q/nuxt-js-i18n-language-postfix-urls-custom-routes/#related-questions","name":"Nuxt.js i18n: Language Postfix URLs with Custom Routes","description":"Learn to configure Nuxt.js i18n for language postfix URLs like /foo/kz using custom routes. Step-by-step guide for module-level and page-level setup.","url":"https://neuroanswers.net/c/web/q/nuxt-js-i18n-language-postfix-urls-custom-routes","inLanguage":"en","mainEntity":{"@type":"ItemList","@id":"https://neuroanswers.net/c/web/q/nuxt-js-i18n-language-postfix-urls-custom-routes/#related-questions","itemListElement":[{"@type":"ListItem","@id":"https://neuroanswers.net/c/web/q/fix-prettier-not-formatting-vscode-nuxt","name":"Fix Prettier Not Formatting in VS Code for Nuxt Apps","position":1,"item":{"@type":"Article","@id":"https://neuroanswers.net/c/web/q/fix-prettier-not-formatting-vscode-nuxt","mainEntityOfPage":{"@type":"WebPage","@id":"https://neuroanswers.net/c/web/q/fix-prettier-not-formatting-vscode-nuxt"},"inLanguage":"en","dateCreated":"2026-02-01T11:09:26.614Z","datePublished":"2026-02-01T11:09:26.614Z","dateModified":"2026-02-01T11:09:26.614Z","author":[{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}}],"publisher":{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}},"headline":"Fix Prettier Not Formatting in VS Code for Nuxt Apps","description":"Learn how to fix Prettier not formatting code in VS Code for Nuxt applications. Configure ESLint, install prettier-plugin-vue, and set up format on save.","keywords":["prettier vscode","prettier eslint","nuxt prettier","prettier not working","prettier vue","eslint config prettier","eslint plugin prettier","vs code prettier format on save","prettier format on save","prettier-plugin-vue","nuxt eslint configuration"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://neuroanswers.net/c/web/q/fix-express-res-json-array-response-issue","name":"Fix Express.js res.json() Array Response Issue - Last Element Only","position":2,"item":{"@type":"Article","@id":"https://neuroanswers.net/c/web/q/fix-express-res-json-array-response-issue","mainEntityOfPage":{"@type":"WebPage","@id":"https://neuroanswers.net/c/web/q/fix-express-res-json-array-response-issue"},"inLanguage":"en","dateCreated":"2025-12-28T15:27:43.001Z","datePublished":"2025-12-28T15:27:43.001Z","dateModified":"2025-12-28T15:27:43.001Z","author":[{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}}],"publisher":{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}},"headline":"Fix Express.js res.json() Array Response Issue - Last Element Only","description":"Learn how to fix Express.js res.json() returning only the last element of an array instead of the full array. Solutions for proper array handling in Express APIs.","keywords":["express json","express array","res.json array","json response","array handling","express api","node.js","javascript arrays","forEach loop","array push","json stringify","express middleware","api response","array methods","json parsing"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://neuroanswers.net/c/web/q/customize-remove-button-orbeon-builder-repeatable-sections","name":"Customize Remove Button in Orbeon Builder Repeatable Sections","position":3,"item":{"@type":"Article","@id":"https://neuroanswers.net/c/web/q/customize-remove-button-orbeon-builder-repeatable-sections","mainEntityOfPage":{"@type":"WebPage","@id":"https://neuroanswers.net/c/web/q/customize-remove-button-orbeon-builder-repeatable-sections"},"inLanguage":"en","dateCreated":"2026-02-11T14:15:08.361Z","datePublished":"2026-02-11T14:15:08.361Z","dateModified":"2026-02-11T14:15:08.361Z","author":[{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}}],"publisher":{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}},"headline":"Customize Remove Button in Orbeon Builder Repeatable Sections","description":"Learn how to customize the remove button label in Orbeon Builder for repeatable sections. Change 'Remove line' to context-specific text and localize for multiple languages.","keywords":["Orbeon remove button","customize repeatable sections Orbeon","Orbeon Builder remove label","repeatable section grid Orbeon","how to change remove button text Orbeon 2022.1","Orbeon forms localize remove iteration label","XML customize remove button repeatable sections","Orbeon Builder remove button customization","Orbeon repeatable sections remove label","localize remove label Orbeon"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://neuroanswers.net/c/web/q/fix-nuxt-3-trailing-slash-redirect-baseurl","name":"Fix Nuxt 3 Trailing Slash Redirect on baseURL","position":4,"item":{"@type":"Article","@id":"https://neuroanswers.net/c/web/q/fix-nuxt-3-trailing-slash-redirect-baseurl","mainEntityOfPage":{"@type":"WebPage","@id":"https://neuroanswers.net/c/web/q/fix-nuxt-3-trailing-slash-redirect-baseurl"},"inLanguage":"en","dateCreated":"2026-02-12T18:38:23.605Z","datePublished":"2026-02-12T18:38:23.605Z","dateModified":"2026-02-12T18:38:23.605Z","author":[{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}}],"publisher":{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}},"headline":"Fix Nuxt 3 Trailing Slash Redirect on baseURL","description":"Stop Nuxt 3 automatic 301 redirects from /travel to /travel/ with app.baseURL: '/travel'. Use simple global middleware to disable trailing slash normalization for index routes without config changes or SEO issues.","keywords":["nuxt 3 trailing slash","nuxt baseurl","trailing slash redirect","nuxt middleware","nitro redirect","nuxt 3 router","disable trailing slash","nuxt seo","baseurl trailing slash"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://neuroanswers.net/c/web/q/migrating-vue-3-to-react-typescript-benefits","name":"Vue 3 to React Migration: TS Predictability Benefits","position":5,"item":{"@type":"Article","@id":"https://neuroanswers.net/c/web/q/migrating-vue-3-to-react-typescript-benefits","mainEntityOfPage":{"@type":"WebPage","@id":"https://neuroanswers.net/c/web/q/migrating-vue-3-to-react-typescript-benefits"},"inLanguage":"en","dateCreated":"2026-01-25T15:51:02.761Z","datePublished":"2026-01-25T15:51:02.761Z","dateModified":"2026-01-25T15:51:02.761Z","author":[{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}}],"publisher":{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}},"headline":"Vue 3 to React Migration: TS Predictability Benefits","description":"Discover technical benefits of migrating from Vue 3 (Composition API, Pinia, TypeScript) to React for better predictability, maintenance, unidirectional data flow, explicit hooks, and superior React TypeScript integration in microfrontends.","keywords":["vue 3","react typescript","vue vs react","vue 3 composition api","react hooks","pinia vue 3","microfrontends","hexagonal architecture","vue react migration","typescript react js","composition api","react unidirectional flow"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://neuroanswers.net/c/web/q/fix-composer-phpspreadsheet-minimum-stability-error-php-8-2","name":"Fix Composer PhpSpreadsheet Minimum-Stability Error on PHP 8.2","position":6,"item":{"@type":"Article","@id":"https://neuroanswers.net/c/web/q/fix-composer-phpspreadsheet-minimum-stability-error-php-8-2","mainEntityOfPage":{"@type":"WebPage","@id":"https://neuroanswers.net/c/web/q/fix-composer-phpspreadsheet-minimum-stability-error-php-8-2"},"inLanguage":"en","dateCreated":"2026-02-11T14:08:33.798Z","datePublished":"2026-02-11T14:08:33.798Z","dateModified":"2026-02-11T14:08:33.798Z","author":[{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}}],"publisher":{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}},"headline":"Fix Composer PhpSpreadsheet Minimum-Stability Error on PHP 8.2","description":"Step-by-step guide to fix 'composer minimum-stability stable' error for phpoffice/phpspreadsheet on PHP 8.2. Proper installation with Composer.","keywords":["phpspreadsheet","composer phpspreadsheet","composer minimum-stability","phpoffice phpspreadsheet","composer stability","phpspreadsheet php 8.2","composer error could not find version phpspreadsheet","phpspreadsheet composer.json no present","invalidargumentexception composer phpspreadsheet","runtimeexception composer.json phpspreadsheet","composer ignore minimum-stability phpspreadsheet","phpspreadsheet matching your minimum-stability stable","how to set composer minimum-stability dev","phpspreadsheet composer update php 8.2","error composer phpspreadsheet stable version","phpoffice phpspreadsheet require explicit version","composer.json minimum-stability stable fix"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://neuroanswers.net/c/web/q/curl-authorization-header-complete-guide","name":"curl authorization header: Complete Guide for API Authentication","position":7,"item":{"@type":"Article","@id":"https://neuroanswers.net/c/web/q/curl-authorization-header-complete-guide","mainEntityOfPage":{"@type":"WebPage","@id":"https://neuroanswers.net/c/web/q/curl-authorization-header-complete-guide"},"inLanguage":"en","dateCreated":"2026-02-14T11:36:02.336Z","datePublished":"2026-02-14T11:36:02.336Z","dateModified":"2026-02-14T11:36:02.336Z","author":[{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}}],"publisher":{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}},"headline":"curl authorization header: Complete Guide for API Authentication","description":"Learn how to set curl authorization headers for Basic Auth, Bearer tokens, and custom authentication. Complete guide with examples and best practices for secure API access.","keywords":["curl authorization header","curl h authorization","curl authorization bearer","curl basic auth","curl headers authorization","curl bearer token","curl api key","curl authentication","curl command authentication","curl authorization methods","curl token authentication","curl custom headers","curl secure authentication"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://neuroanswers.net/c/web/q/sync-trumbowyg-editors-alpine-js","name":"Alpine.js: Sync Trumbowyg Vertical Scrolling with Code","position":8,"item":{"@type":"Article","@id":"https://neuroanswers.net/c/web/q/sync-trumbowyg-editors-alpine-js","mainEntityOfPage":{"@type":"WebPage","@id":"https://neuroanswers.net/c/web/q/sync-trumbowyg-editors-alpine-js"},"inLanguage":"en","dateCreated":"2026-01-05T16:35:48.554Z","datePublished":"2026-01-05T16:35:48.554Z","dateModified":"2026-01-05T16:35:48.554Z","author":[{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}}],"publisher":{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}},"headline":"Alpine.js: Sync Trumbowyg Vertical Scrolling with Code","description":"Sync vertical scrolling between two Trumbowyg editors using Alpine.js or vanilla JS. Keeps toolbars visible and avoids page scrolling. Includes runnable code.","keywords":["trumbowyg","alpine js","sync scroll","vanilla js","trumbowyg-editor","fixedBtnPane","syncscroll","scrollTop","editor sync","contenteditable","toolbar visibility","requestAnimationFrame"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://neuroanswers.net/c/web/q/why-bootstrap-modal-shown-bs-modal-fires-twice-react-useeffect","name":"Why Bootstrap Modal shown.bs.modal Fires Twice in React useEffect","position":9,"item":{"@type":"Article","@id":"https://neuroanswers.net/c/web/q/why-bootstrap-modal-shown-bs-modal-fires-twice-react-useeffect","mainEntityOfPage":{"@type":"WebPage","@id":"https://neuroanswers.net/c/web/q/why-bootstrap-modal-shown-bs-modal-fires-twice-react-useeffect"},"inLanguage":"en","dateCreated":"2026-02-27T16:56:15.735Z","datePublished":"2026-02-27T16:56:15.735Z","dateModified":"2026-02-27T16:56:15.735Z","author":[{"@type":"Person","@id":"https://neuroanswers.net/@joe-lloyd","name":"Joe Lloyd","givenName":"Joe","familyName":"Lloyd","url":"https://neuroanswers.net/@joe-lloyd","jobTitle":"Frontend Developer","description":"Specialised in frontend development since 2013, living in Amsterdam. Active on Stack Overflow with 22,843 reputation, 336 answers, and 104 questions, focusing on ReactJS, JavaScript, AngularJS, HTML, CSS, and Redux."},{"@type":"Person","@id":"https://neuroanswers.net/@md-yeasin-arafat","name":"Md Yeasin Arafat","givenName":"Md Yeasin","familyName":"Arafat","url":"https://neuroanswers.net/@md-yeasin-arafat","jobTitle":"Web and Android Developer","description":"PHP Web Developer and Android Apps Developer using Java. Expertise in ReactJS and React Hooks. Stack Overflow reputation: 4,059 with 3 answers."},{"@type":"Person","@id":"https://neuroanswers.net/@taig","name":"@taig","url":"https://neuroanswers.net/@taig","jobTitle":"Software Developer","description":"Developer with expertise in Android, ReactJS, Java, Scala, and CSS. Stack Overflow reputation: 7,428 with 69 answers and 68 questions."},{"@type":"Person","@id":"https://neuroanswers.net/@ilan-weissberg","name":"ilan weissberg","givenName":"ilan","familyName":"weissberg","url":"https://neuroanswers.net/@ilan-weissberg","jobTitle":"Full Stack Developer","description":"Full stack Ruby on Rails developer with knowledge in JavaScript, jQuery, and HTML. Stack Overflow reputation: 668 with 13 answers and 2 questions."},{"@type":"Person","@id":"https://neuroanswers.net/@smoksnes","name":"@smoksnes","url":"https://neuroanswers.net/@smoksnes","jobTitle":"Developer","description":"Active Stack Overflow contributor with 10.9k reputation."},{"@type":"Person","@id":"https://neuroanswers.net/@benard-patrick","name":"BENARD Patrick","givenName":"BENARD","familyName":"Patrick","url":"https://neuroanswers.net/@benard-patrick","jobTitle":"Software Developer","description":"Experienced software developer specializing in front-end technologies like React and Bootstrap."},{"@type":"Organization","@id":"https://neuroanswers.net/@getbootstrap-com","name":"Bootstrap","description":"Free and open-source CSS framework for responsive mobile-first websites","url":"https://neuroanswers.net/@getbootstrap-com","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/api/v1/source/getbootstrap-com/icon.png","width":"72","height":"72"}},{"@type":"Person","@id":"https://neuroanswers.net/@steven-scaffidi","name":"Steven Scaffidi","givenName":"Steven","familyName":"Scaffidi","url":"https://neuroanswers.net/@steven-scaffidi","jobTitle":"JavaScript Developer","description":"Developer focused on JavaScript, ReactJS, and React Native. Stack Overflow reputation: 2,307 with 28 answers and 6 questions."},{"@type":"Person","@id":"https://neuroanswers.net/@barbara-f","name":"Barbara F","givenName":"Barbara","familyName":"F","url":"https://neuroanswers.net/@barbara-f","jobTitle":"Developer","description":"Stack Overflow user contributing on topics like HTML, jQuery, JavaScript, and Bootstrap modals. Reputation: 1."}],"publisher":{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}},"headline":"Why Bootstrap Modal shown.bs.modal Fires Twice in React useEffect","description":"Learn why Bootstrap 'shown.bs.modal' event fires twice in React useEffect (empty deps, no StrictMode) but once in plain JS. Fixes include cleanup, ref guards, and react bootstrap alternatives for reliable modal events.","keywords":["useeffect","react bootstrap","bootstrap modal","shown.bs.modal","bootstrap 5 modal","useeffect twice","react modal events","addEventListener"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://neuroanswers.net/c/web/q/object-spread-vs-object-assign-merge-default-options","name":"Object Spread vs Object.assign: Pros & Cons for Merging Options","position":10,"item":{"@type":"Article","@id":"https://neuroanswers.net/c/web/q/object-spread-vs-object-assign-merge-default-options","mainEntityOfPage":{"@type":"WebPage","@id":"https://neuroanswers.net/c/web/q/object-spread-vs-object-assign-merge-default-options"},"inLanguage":"en","dateCreated":"2026-02-27T17:50:31.814Z","datePublished":"2026-02-27T17:50:31.814Z","dateModified":"2026-02-27T17:50:31.814Z","author":[{"@type":"Person","@id":"https://neuroanswers.net/@mdn-contributors","name":"@mdn-contributors","url":"https://neuroanswers.net/@mdn-contributors","jobTitle":"Technical Writer","description":"Global community of volunteers and partners collaborating with Mozilla to create, translate, and maintain documentation on web technologies."},{"@type":"Organization","@id":"https://neuroanswers.net/@developer-mozilla-org","name":"MDN Web Docs","description":"Open-source, collaborative project owned by Mozilla Corporation that provides free, comprehensive documentation on open web technologies including HTML, CSS, JavaScript, Web APIs, and tools for web developers, maintained by Mozilla and a global community of volunteers.","url":"https://neuroanswers.net/@developer-mozilla-org","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/api/v1/source/developer-mozilla-org/logo.png","width":"72","height":"72"}},{"@type":"Person","@id":"https://neuroanswers.net/@jmm","name":"@jmm","url":"https://neuroanswers.net/@jmm","jobTitle":"Software Developer","description":"Software and web application developer specializing in open source, web standards, API design, maintainability, and documentation."},{"@type":"Person","@id":"https://neuroanswers.net/@user1902408","name":"@user1902408","url":"https://neuroanswers.net/@user1902408","jobTitle":"Developer","description":"Contributor to Stack Overflow discussions on JavaScript and related programming topics."},{"@type":"Person","@id":"https://neuroanswers.net/@sandre89","name":"@sandre89","url":"https://neuroanswers.net/@sandre89","jobTitle":"Developer","description":"Active Stack Overflow contributor with expertise in Ruby on Rails, JavaScript, Ruby, ActiveRecord, and web development, holding high reputation through numerous questions and answers."},{"@type":"Organization","@id":"https://neuroanswers.net/@stackoverflow-com","name":"Stack Overflow","description":"Question and answer site for professional and enthusiast programmers","url":"https://neuroanswers.net/@stackoverflow-com","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/api/v1/source/stackoverflow-com/logo.png","width":"72","height":"72"}},{"@type":"Organization","@id":"https://neuroanswers.net/@www-geeksforgeeks-org","name":"GeeksforGeeks","description":"Comprehensive educational platform offering computer science and programming articles, tutorials, quizzes, practice problems, interview preparation, competitive programming, and resources across domains like data structures, algorithms, web development, and exams.","url":"https://neuroanswers.net/@www-geeksforgeeks-org","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/api/v1/source/www-geeksforgeeks-org/logo.png","width":"72","height":"72"}},{"@type":"Person","@id":"https://neuroanswers.net/@code-barbarian","name":"Valeri Karpov","givenName":"Valeri","familyName":"Karpov","url":"https://neuroanswers.net/@code-barbarian","image":{"@type":"ImageObject","url":"https://neuroanswers.net/api/v1/person/code-barbarian/avatar.png","width":"72","height":"72"},"jobTitle":"Software Developer","description":"Maintainer of Mongoose (MongoDB ODM for Node.js), founder of MeanIT Software (boutique development shop), and author of The Code Barbarian blog on Node.js, JavaScript, and MongoDB topics."},{"@type":"Organization","@id":"https://neuroanswers.net/@thecodebarbarian-com","name":"The Code Barbarian","description":"Personal developer blog focused on JavaScript, Node.js, MongoDB, Mongoose, and related topics, featuring tutorials, updates on tools like Mongoose Studio, and development insights.","url":"https://neuroanswers.net/@thecodebarbarian-com","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/api/v1/source/thecodebarbarian-com/icon.png","width":"72","height":"72"}}],"publisher":{"@type":"Organization","@id":"https://neuroanswers.net/about","name":"NeuroAnswers","url":"https://neuroanswers.net/about","logo":{"@type":"ImageObject","url":"https://neuroanswers.net/logo.png","width":"512","height":"512"}},"headline":"Object Spread vs Object.assign: Pros & Cons for Merging Options","description":"Compare object spread operator `{ ...defaults, ...options }` vs Object.assign for merging default options in JavaScript. Explore immutability, performance, browser support, and best use cases for clean, efficient object merging.","keywords":["object spread","object assign","spread operator","merge objects javascript","default options javascript","object spread vs object assign","js spread operator","immutable object merge","javascript object merging"],"image":[],"articleBody":""}}]}}]}
Web

Nuxt.js i18n: Language Postfix URLs with Custom Routes

Learn to configure Nuxt.js i18n for language postfix URLs like /foo/kz using custom routes. Step-by-step guide for module-level and page-level setup.

1 answer 2 views

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

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:

  1. First, ensure your i18n configuration includes the customRoutes option set to ‘config’:
typescript
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n'],
  
  i18n: {
    strategy: 'prefix_except_default',
    customRoutes: 'config',
    // ... other i18n configurations
  }
})
  1. Then, define your custom routes in the pages section 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’ } }”
typescript
// 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:

  1. First, ensure your i18n configuration is set up with the custom routes strategy:
typescript
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n'],
  
  i18n: {
    strategy: 'prefix_except_default',
    customRoutes: 'page',
    // ... other i18n configurations
  }
})
  1. Then, in your page component, define the custom route:
vue
<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:

typescript
// 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:

vue
<!-- 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:

vue
<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:

  1. Consistency: Maintain consistent URL patterns across your entire application for better user experience and SEO.

  2. Readability: Ensure your language postfixes are intuitive. Using /foo/kz is clearer than /foo-kz as it visually separates the language code from the actual path.

  3. Navigation: Provide clear language switchers that help users understand how to navigate between different language versions.

  4. Browser Language Detection: Configure the detectBrowserLanguage option to automatically redirect users to their preferred language version:

typescript
// nuxt.config.ts
i18n: {
  detectBrowserLanguage: {
    useCookie: true,
    cookieKey: 'i18n_redirected',
    redirectOn: 'root',
    fallbackLocale: 'en'
  }
}
  1. Fallback Handling: Always provide a fallback to your default language when content isn’t available in the requested language.

  2. Testing: Thoroughly test your routing behavior, especially with edge cases like empty routes, nested routes, and dynamic parameters.

  3. 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:

typescript
// 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:

typescript
// 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.

Sources

Authors
Verified by moderation
NeuroAnswers
Moderation
Nuxt.js i18n: Language Postfix URLs with Custom Routes