Guide

Different Domains

Use a different domain name for each language your app supports.

You might want to use a different domain name for each language your app supports.

Here is how to achieve this:

  • Set differentDomains option to true
  • Configure the locales option as an array of objects, where each object has a domain key whose value is the domain name you'd like to use for that locale. Optionally include a port (if non-standard) and/or a protocol. If the protocol is not provided then an attempt will be made to auto-detect it but that might not work correctly in some cases like when the pages are statically generated.
  • Optionally set detectBrowserLanguage to false. When enabled (which it is by default), user can get redirected to a different domain on first visit. Set to false if you want to ensure that visiting given domain always shows page in the corresponding locale.
nuxt.config.ts
export default defineNuxtConfig({
  i18n: {
    locales: [
      {
        code: 'en',
        domain: 'mydomain.com'
      },
      {
        code: 'es',
        domain: 'es.mydomain.com'
      },
      {
        code: 'fr',
        domain: 'fr.mydomain.com'
      },
      {
        code: 'pl',
        domain: 'http://pl.mydomain.com'
      },
      {
        code: 'ua',
        domain: 'https://ua.mydomain.com'
      }
    ],
    differentDomains: true
    // Or enable the option in production only
    // differentDomains: (process.env.NODE_ENV === 'production')
  }
})

When using different domain names, your lang switcher should use regular <a> tags:

<script setup>
const { locale, locales } = useI18n()
const switchLocalePath = useSwitchLocalePath()

const availableLocales = computed(() => {
  return locales.value.filter(i => i.code !== locale.value)
})
</script>

<template>
  ...
  <a v-for="locale in availableLocales" :href="switchLocalePath(locale.code)" :key="locale.code">
    {{ locale.code }}
  </a>
  ...
</template>

Runtime environment variables

Sometimes there's a need to change domains in different environments, e.g. staging and production. As nuxt.config.ts is used at build time it would be necessary to create different builds for different environments.

locale-domains.config.ts
export const localeDomains = {
  uk: process.env.DOMAIN_UK,
  fr: process.env.DOMAIN_FR
}
nuxt.config.ts
import { localeDomains } from './locale-domains.config'

export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n'],

  i18n: {
    differentDomains: process.env.NODE_ENV === 'production',
    locales: [
      {
        code: 'uk',
        domain: localeDomains.uk
      },
      {
        code: 'fr',
        domain: localeDomains.fr
      }
    ]
  }
})

With the above config, a build would have to be run for staging and production with different .env files that specify DOMAIN_UK and DOMAIN_FR.

Alternatively, to avoid the need for multiple builds, the locale domains can be overridden via runtime environment variables. The variable name should follow the format NUXT_PUBLIC_I18N_LOCALES_{locale code}_DOMAIN

For example:

production.env
NUXT_PUBLIC_I18N_LOCALES_UK_DOMAIN=uk.example.test
NUXT_PUBLIC_I18N_LOCALES_FR_DOMAIN=fr.example.test
staging.env
NUXT_PUBLIC_I18N_LOCALES_UK_DOMAIN=uk.staging.example.test
NUXT_PUBLIC_I18N_LOCALES_FR_DOMAIN=fr.staging.example.test

Using different domains for only some of the languages

If one or more of the domains need to host multiple languages, the default language of each domain needs to have domainDefault: true so there is a per domain fallback locale. The option differentDomains still need to be set to true though.

nuxt.config.js
export default defineNuxtConfig({
  // ...
  i18n: {
    locales: [
      {
        code: 'en',
        domain: 'mydomain.com',
        domainDefault: true
      },
      {
        code: 'pl',
        domain: 'mydomain.com'
      },
      {
        code: 'ua',
        domain: 'mydomain.com'
      },
      {
        code: 'es',
        domain: 'es.mydomain.com',
        domainDefault: true
      },
      {
        code: 'fr',
        domain: 'fr.mydomain.com',
        domainDefault: true
      }
    ],
    strategy: 'prefix',
    differentDomains: true
    // Or enable the option in production only
    // differentDomains: (process.env.NODE_ENV === 'production')
  },
  // ...
})

Given above configuration with the prefix strategy, following requests will be:

The same requests when using the prefix_except_default strategy, will be:


Copyright © 2024