easwee.net // tiny digital playground

testing domain level localization on localhost

This approach is useful when you are making a multilanguage website that starts localizing already at domain level - meaning that each domain caters to it's own locale.

First add custom local domains to your hosts file. Make them unique and make sure they are not registered domains:

127.0.0.1       mylocaldomainxyz.com
127.0.0.1       mylocaldomainxyz.ch
127.0.0.1       mylocaldomainxyz.fr
127.0.0.1       mylocaldomainxyz.de

If you pick registered domain names like test.com or similar, HSTS will kick in and it will force redirect your local domain to https. In Firefox you can disable HSTS list preloading by setting network.stricttransportsecurity.preloadlist to false in about:config, I couldn't manage to disable it in latest Chrome - also didn't bother much since using unique local domains is way more simple.

Now I want to use this with latest NextJS (at the time of writing v10).

Simple enough it can now all be configured in next.config.js without the need of any additional libraries:

module.exports = {
  i18n: {
    http: true,
    locales: ["en", "fr", "de", "fr-CH", "it-CH", "de-CH"],
    defaultLocale: "en",
    domains: [
      {
        http: true,
        domain: "mylocaldomainxyz.com:3000",
        defaultLocale: "en",
      },
      {
        http: true,
        domain: "mylocaldomainxyz.de:3000",
        defaultLocale: "de",
      },
      {
        http: true,
        domain: "mylocaldomainxyz.fr:3000",
        defaultLocale: "fr",
      },
      {
        http: true,
        domain: "mylocaldomainxyz.ch:3000",
        defaultLocale: "de-CH",
        locales: ["fr-CH", "it-CH"],
      },
    ],
  }
};

The entry for Swiss uses multiple locales - default locale when hitting mylocaldomainxyz.ch will be German; French and Italian versions will be available on mylocaldomainxyz.ch/fr-CH and mylocaldomainxyz.ch/it-CH. Language detection is triggered only when hitting root index page. You can rewrite the urls if -CH suffix looks like overhead, but you will need to have the locales defined correctly, since de locale is not same as de-CH, ISO standard applies. For more configuration and usage options check NextJS Internationalized Routing docs.

Optional:

If you are running your apps on a custom port (3000 is popular) and find it annoying to have port appended to your custom url, you can redirect default port 80 to whatever port you want using iptables:

sudo iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 3000

You can now access your app directly without specifying port: http://mylocaldomainxyz.fr

To remove the output redirect when you don't need it anymore, first get numbered list of output redirects:

sudo iptables -t nat -v -L OUTPUT -n --line-number

A list of redirects is returned.

Check which line number is your custom redirect and remove it:

sudo iptables -t nat -D OUTPUT 3

Entry with line number 3 is removed.