简体   繁体   中英

Sub-path routing same locale across different domain routes (Next.JS & i18n)

The task at hand:

A website, that functions across multiple countries, having it's own range of products/services/etc. for each country. It also needs to have translation to a different language, depending on the country/TLD. Translation languages should repeat on some domains. The outcome should be something like this:

US
sitename.com - US market, english language (US)

Germany
sitename.de - native language
sitename.de/en - english language (INT)

France
sitename.fr - native language
sitename.fr/en - english language (INT)

Netherlands
sitename.nl - native language
sitename.nl/en - english language (INT)

United Kingdom
sitename.co.uk - english language (GB)

Current state:

In my next.config.js I have a domain routing configuration, which resembles the following example:

module.exports = {
  ...
  i18n: {
    localeDetection: false,
    defaultLocale: 'en',
    locales: [],
    domains: [
      {
        domain: 'sitename.com',
        defaultLocale: 'en-US', 
        locales: []
      },
      {
        domain: 'sitename.de',
        defaultLocale: 'de-DE', 
        locales: ['en']
      },
      {
        domain: 'sitename.fr',
        defaultLocale: 'fr-FR', 
        locales: ['en']
      },
      {
        domain: 'sitename.nl',
        defaultLocale: 'nl-NL', 
        locales: ['en']
      },
      {
        domain: 'sitename.co.uk',
        defaultLocale: 'en-GB', 
        locales: []
      },
      // list of countries goes on ...
    ]
  }
}

Unfortunately, Next.JS doesn't like my conf ideas and refuses to work with me, throwing the following error:

Both sitename.de and sitename.fr configured the locale (en) but only one can. Remove it from one i18n.domains config to continue
Both sitename.fr and sitename.de configured the locale (en) but only one can. Remove it from one i18n.domains config to continue
Both sitename.nl and sitename.de configured the locale (en) but only one can. Remove it from one i18n.domains config to continue
Error: Invalid i18n.domains values:
{"domain":"sitename.de","defaultLocale":"de-DE","locales":["en"]}
{"domain":"sitename.fr","defaultLocale":"fr-FR","locales":["en"]}
{"domain":"sitename.nl","defaultLocale":"nl-NL","locales":["en"]}

domains value must follow format { domain: 'example.fr', defaultLocale: 'fr', locales: ['fr'] }.
See more info here: https://nextjs.org/docs/messages/invalid-i18n-config

Question:

Is there any way to actually implement this kind of localization in NEXT.JS, where certain domains share a language, but not necessarily need to have every other language in the list?

  1. Add all supported locales into array on root of i18n
    locales: ["en-US", "de-DE", "fr-FR", "nl-NL"...]
  1. Remove locales array from domains items. Leave only if you want that locale to redirect to that domain. The way you wrote it, every en option will redirect to 3 different domains
   {
        domain: 'sitename.de',
        defaultLocale: 'de-DE', 
        locales: ['en']
      },
      {
        domain: 'sitename.fr',
        defaultLocale: 'fr-FR', 
        locales: ['en']
      },
      {
        domain: 'sitename.nl',
        defaultLocale: 'nl-NL', 
        locales: ['en']
      }

You need to remove that array and leave only if you want that locale to redirect to that domain.

Regarding that outcome in the first part still note able to do that with pure nextjs since each locale has different domain and will be redirected there.

There is one solution: https://github.com/tomsoderlund/nextjs-multi-domain-locale but is not working for me.

You can setup multiple domains with multiple locales support and without domain redirections using the following approach:

  1. Change your locale switch code from this:
const { pathname, asPath, query } = router
router.push({ pathname, query }, asPath, { locale: newLocale })

to this:

const { pathname, asPath, query, defaultLocale } = router
router.push({ pathname, query }, asPath, {
    locale: newLocale === defaultLocale
        ? 'default-locale'
        : `locale-${newLocale}`
})

This will disable domain routing and redirection because of using locales not from the list.

  1. Redirect custom locales to the proper ones in your next.config.js :
async redirects() {
    return [
        {
            source: '/default-locale/:slug*',
            destination: '/:slug*',
            permanent: false,
        },
        {
            source: '/locale-:locale/:slug*',
            destination: '/:locale/:slug*',
            permanent: false,
        },
    ];
}
  1. Setup domains in i18n section of next.config.js :
i18n: {
    defaultLocale: 'en',
    locales: ['en', 'fr'],
    localeDetection: false,
    domains: [
        {
            domain: 'example.en',
            defaultLocale: 'en',
        },
        {
            domain: 'example.fr',
            defaultLocale: 'fr',
        },
    ],
}

And thats it!

You're likely missing env variables. Check with your team that you have everything you need locally in your.env file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM