Next.js global variables on server and client based on request domain

Hen*_*ava 11 reactjs next.js

I am working on a Next.js multisite scoped project and I need to create a set of global variables to use on client and server (during SSR) side.

So far I came to the below solution.

This is how my custom App looks like:

import App from 'next/app'
import multisite from '@utils/multisite';
import MultisiteProvider from '@components/multisite/MultisiteProvider';

function MyApp({
  Component,
  site,
  pageProps
}) {
  // Will add site props to every page
  const props = { ...pageProps, site };
  return (
    // Provider will enable a hook to get site props on any child component
    <MultisiteProvider site={ site } >
      <Component { ...props }/>
    </MultisiteProvider>
  )
}

MyApp.getInitialProps = async(appContext) => {
  // getInitialProps executes on every page access, even on client when using "next/link"

  const appProps = await App.getInitialProps(appContext);
  let host;
  if (appContext.ctx.req) {
    // Get host from request during SSR
    host = appContext.ctx.req.headers.host;
  } else {
    // Get host from window on client
    host = window.location.host;
  }

  return {
    ...appProps,
    site: await multisite.resolveSiteProps(host)
  };
}

export default MyApp;
Run Code Online (Sandbox Code Playgroud)

I would like to avoid using getInitialProps because it was supposed to disable Automatic Static Optimization in pages without Static Generation (which is my case). As mentioned on docs

The variables for each site are located on a "sites" directory under root folder like this:

/sites
--/siteone.com.us.json
--/siteone.com.br.json
--/sitetwo.com.us.json
Run Code Online (Sandbox Code Playgroud)

And there is a function used to load the right file based on the current request domain.

const resolveSiteProps = async(host) => {
  const domain = normalizeDomain(host);
  const site = await
  import (
    /* webpackChunkName: "site-prefs" */
    /* webpackMode: "lazy" */
    `../sites/${domain}`
  );
  return {
    ...site.default,
    domain
  };
}
Run Code Online (Sandbox Code Playgroud)

It would be nice if I could resolve this variables once during SSR and just use them in the client side.

I am looking for some helpful and elegant ideas to solve this case. Any thoughts?

小智 1

只是很快地尝试了这个解决方案,但这至少在理论上应该有效,但这是一种不同的方法。我们使用基于主机的重写,但问题略有不同。此外,我们确实有一个与您最初发布的类似解决方案,用于根据请求主机决定品牌。

如果每个站点都有不同的路径,然后根据主机在 next.config.js 中使用重写,该怎么办?

脚步:

  1. 为页面中的每个站点添加子文件夹,例如pages/siteone和pages/sitetwo
  2. 根据站点主机添加重写,如下所示
async rewrites() {
{
        source: '/:path*',
        destination: '/siteone/:path',
        has: [
          {
            type: 'host',
            value: 'siteone.com.us',
          },
        ],
      },
}
Run Code Online (Sandbox Code Playgroud)

当然,这会带来必须拥有每个站点的所有页面的成本,但您可以共享大部分代码,所以希望这不是问题。

注意:这可能不是一个功能齐全的示例,但至少它为您提供了有关在 Next.js 中重写可能实现的功能的提示。

https://nextjs.org/docs/api-reference/next.config.js/rewrites