Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieving sub-domain in Next.js page

I have a pages/index.tsx Next.js page whose code looks like this:

import { ApolloProvider } from "@apollo/react-hooks"
import Client from "../db"

import Header from "../components/Header"

export default function Index() {
    return <ApolloProvider client={Client}>
        <Header langKey={langKey} />
    </ApolloProvider>
}

The problem is, langKey is supposed to be the sub-domain from which the page is accessed (for instance, en.localhost:3000 or fr.localhost:3000; langKey would be en or fr). How do I retrieve this information from the Next.js context? I tried the Router object, but it doesn't look like it stores any URL information before the first /.

like image 851
Algorythmis Avatar asked Aug 13 '19 00:08

Algorythmis


2 Answers

On the getInitialProps lifecycle method (doc's here) you can access the request object on the server-side and parse the host header.

Index.getInitialProps = async ({ req }) => {
  const subdomain = req.headers.host.split('.')[0];
  return { langkey: subdomain };
};

If this information is only needed on the client side you could just as easily parse window.location somewhere in a lifecycle method with: window.location.host.split('.')[0].

Hope that helps!

like image 113
Scott Powell Avatar answered Oct 18 '22 14:10

Scott Powell


I ran into a similar problem recently and found a different, simple solution: you can use rewrites to put the hostname into the path as a path variable. This works on both server side and client side, though I only tested it with pages that use getStaticPaths/getStaticProps; there may be issues with other types of page rendering.

Just add something like this to next.config.js:

        rewrites: async () => {
            // In order to support wildcard subdomains with different content, use a "rewrite" to include the host in the path
            return [
                {
                    source: '/:path*{/}?',
                    has: [
                        {
                            type: 'host',
                            value: '(?<siteHost>.*)',
                        },
                    ],
                    destination: '/site/:siteHost/:path*',
                },
            ];
        },

Note 1: This rewrite is used only if the initial request doesn't match a file in /pages/ so to test it you'll need to move your existing content into the site subfolder, e.g. move pages/index.tsx to pages/site/[siteHost]/index.tsx

Note 2: using source: '/:path*' won't work with the homepage (/) due to https://github.com/vercel/next.js/issues/14930 - that's why this uses source: '/:path*{/}?'

like image 39
bradenm Avatar answered Oct 18 '22 15:10

bradenm