You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS 11如何基于域名通过getServerSideProps渲染动态内容?

多租户域名下的Next.js国际化方案

针对你遇到的Next.js官方i18n配置无法支持多域名映射同一locale、且无法通过TLD区分内容的问题,以下是几种可行的替代方案:

1. 用Middleware全局处理域名->Locale映射

Next.js的Middleware可以在请求到达页面之前拦截处理,适合全局统一解析域名并设置Locale,比单独在每个页面的getServerSideProps里处理更高效。

示例代码(middleware.ts):

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

// 定义域名与locale的映射表
const DOMAIN_LOCALE_MAP = {
  'stagingus.sitename.net': 'en-US',
  'staginguk.sitename.net': 'en-GB',
  'sitename.com': 'en-US',
  'dev.sitename.com': 'en-US',
};

export function middleware(request: NextRequest) {
  const host = request.headers.get('host');
  const locale = DOMAIN_LOCALE_MAP[host as keyof typeof DOMAIN_LOCALE_MAP] || 'en-US';

  // 将locale存入请求头,方便后续页面获取
  const requestHeaders = new Headers(request.headers);
  requestHeaders.set('x-locale', locale);

  // 也可以设置cookie,让客户端也能获取到locale
  const response = NextResponse.next({
    request: { headers: requestHeaders },
  });
  response.cookies.set('locale', locale);

  return response;
}

// 指定需要拦截的路由(这里匹配所有路由)
export const config = {
  matcher: '/:path*',
};

之后在页面组件或getServerSideProps中,就可以通过req.headers.get('x-locale')或者cookie获取当前locale,再加载对应内容。

2. 集中式域名配置映射表

如果不想用Middleware,可以在项目中维护一个集中的域名-locale配置文件,在getServerSideProps或getInitialProps中统一匹配,避免每个页面重复写正则。

示例代码(config/domain-locale.ts):

export const domainLocaleMap = new Map<string | RegExp, string>([
  ['stagingus.sitename.net', 'en-US'],
  ['staginguk.sitename.net', 'en-GB'],
  ['sitename.com', 'en-US'],
  ['dev.sitename.com', 'en-US'],
  // 支持通配符匹配,比如所有us开头的staging域名
  [/^stagingus\..+\.net$/, 'en-US'],
  [/^staginguk\..+\.net$/, 'en-GB'],
]);

export function getLocaleFromHost(host: string): string {
  for (const [key, locale] of domainLocaleMap) {
    if (typeof key === 'string') {
      if (host === key) return locale;
    } else if (key.test(host)) {
      return locale;
    }
  }
  return 'en-US'; // 默认locale
}

在页面的getServerSideProps中使用:

import { getLocaleFromHost } from '../config/domain-locale';

export async function getServerSideProps(ctx) {
  const host = ctx.req.headers.host;
  const locale = getLocaleFromHost(host);
  
  // 根据locale获取对应内容
  const content = await fetchContentByLocale(locale);

  return { props: { locale, content } };
}

3. 自定义i18n逻辑(脱离官方i18n配置)

放弃Next.js官方的i18n配置,直接用react-i18next等第三方国际化库,完全通过域名控制语言切换,灵活性更高。

步骤:

  1. 安装依赖:npm install react-i18next i18next
  2. 初始化i18n(i18n.ts):
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

// 导入语言包
import enUS from './locales/en-US.json';
import enGB from './locales/en-GB.json';

const resources = {
  'en-US': { translation: enUS },
  'en-GB': { translation: enGB },
};

i18n.use(initReactI18next).init({
  resources,
  fallbackLng: 'en-US',
  interpolation: { escapeValue: false },
});

export default i18n;
  1. 在_app.tsx中根据域名切换语言:
import { useEffect } from 'react';
import i18n from '../i18n';
import { getLocaleFromHost } from '../config/domain-locale';

function MyApp({ Component, pageProps, locale }) {
  useEffect(() => {
    i18n.changeLanguage(locale);
  }, [locale]);

  return <Component {...pageProps} />;
}

MyApp.getInitialProps = async (appContext) => {
  const host = appContext.ctx.req.headers.host;
  const locale = getLocaleFromHost(host);
  
  const appProps = await typeof App !== 'undefined' ? App.getInitialProps(appContext) : {};
  return { ...appProps, locale };
};

export default MyApp;

4. 结合多租户数据模型

如果你的多租户场景中,每个域名对应一个租户实例,可以在数据库中存储租户与locale的关联关系,通过域名查询租户信息后获取对应的locale。这种方式适合租户数量多、需要动态配置的场景。

示例代码(getServerSideProps中):

export async function getServerSideProps(ctx) {
  const host = ctx.req.headers.host;
  // 从数据库查询租户信息
  const tenant = await db.tenant.findOne({ where: { domain: host } });
  const locale = tenant?.locale || 'en-US';
  
  // 获取对应内容
  const content = await fetchContentByTenant(tenant.id);

  return { props: { locale, content, tenant } };
}

内容的提问来源于stack exchange,提问作者mcclosa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 18:34:58