Search code examples
next.jsinternationalizationmulti-tenant

NextJS 11 rendering dynamic content from getServerSideProps depending on domain?


I have a multitenancy website that has multiple domains with the same tld.

For example

  • stagingus.sitename.net
  • staginguk.sitename.net
  • dev.sitename.co.uk
  • dev.sitename.com
  • dev.sitename.co.uk
  • sitename.com
  • sitename.co.uk
  • site-name.com
  • site-name.co.uk

I initially was going to go down the route of Internationalization, using i18n setting in next.config.js but was thwarted by the fact that you cannot have multiple domains with the same locale, for example

i18n: {
  locales: ['en-GB', 'en-US'],
  defaultLocale: 'en-GB',
  localeDetection: false,
  domains: [
    {
      domain: 'sitename.co.uk',
      defaultLocale: 'en-GB',
    },
    {
      domain: 'sitename.com',
      defaultLocale: 'en-US',
    },
    {
      domain: 'dev.sitename.com',
      defaultLocale: 'en-US',
    },
  ],
},

throws the following error

Both dev.sitename.com and sitename.com configured the defaultLocale en-US but only one can. Change one item's default locale to continue
Error: Invalid i18n.domains values:
{"domain":"sitename.com","defaultLocale":"en-US"}
{"domain":"dev.sitename.com","defaultLocale":"en-US"}

domains value must follow format { domain: 'example.fr', defaultLocale: 'fr', locales: ['fr'] }.

I cannot rely on the TLD either, as stagingus.sitename.net and staginguk.sitename.net both end in .net but would offer different content.

So I am not sure if it's just going to be a case of checking if the current host is a UK or US domain with something like this is in a getServerSideProps function?

const isUS = ctx.req.headers.host.match(someUsDomainRegex));

Unless there is some other method I am unaware of?

Any help would be appreciated


Solution

  • Yes, this is the way to conditionally execute code based on the subdomain of the current domain, you could write your code something like this.

    export async function getServerSideProps(ctx: GetServerSidePropsContext) {
      if (ctx.req.headers.host?.startsWith?.("dev")) {
        return; // ... data for development
      }
      // ...
    }
    

    Of course if you know the sub-domain structure you can always implement a helper function to make this process less tedious and the code reusable so you can implement it in multiple pages:

    export async function getHostType(host: string) {
      const separated = host.split(".");
    
      if (host?.startsWith?.("dev")) {
        return { type: "dev", country: null };
      }
    
      if (host?.startsWith?.("staging")) {
        const country = separated[0].replace("staging", "");
        return { type: "staging", country };
      }
    
      const country = separated[separated.length - 1];
      return { type: "production", country: country !== "com" ? country : null };
    }