首页 / Next.js 16 入门教程 / 多租户与多区域

Next.js 16 入门教程

多租户与多区域

本教程共 42 篇 · 第 42 篇 · 更新于 2026-07-30 · 约 6 分钟阅读

Next.jsNext.js 16 入门教程多租户多区域微前端跨域路由

42. 多租户与多区域

本节目标:理解 Next.js 多区域(Multi-Zones)微前端架构,学会构建多租户应用和跨应用路由。

多区域(Multi-Zones)

多区域是 Next.js 实现微前端的方式。把一个大应用拆成多个独立的小应用,每个应用负责一部分路径,但共享同一个域名。

适用场景

/blog/*     -> 博客应用(独立团队维护)
/dashboard/* -> 后台应用(独立团队维护)
/*          -> 主站应用

拆分的好处:

  • 构建更快:每个应用体积小,构建时间短
  • 独立部署:各团队自主发版,互不影响
  • 技术灵活:不同区域可以用不同框架

导航行为

  • 区域内导航:软导航(不刷新页面)
  • 跨区导航:硬导航(整页刷新)

经常一起访问的页面应该放在同一个区域,避免频繁硬导航。

定义区域

每个区域就是一个普通的 Next.js 应用,但需要配置 assetPrefix 避免资源冲突:

// 博客应用的 next.config.ts
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  assetPrefix: '/blog-static',
}

export default nextConfig

静态资源会发布在 /blog-static/_next/...,不会和其他区域冲突。

主站应用(处理兜底路径)不需要 assetPrefix

路由配置

用 rewrites 路由

在一个 Next.js 应用中配置 rewrite 规则,把请求转发到对应的区域:

// 主站应用的 next.config.ts
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  async rewrites() {
    return [
      {
        source: '/blog',
        destination: `${process.env.BLOG_DOMAIN}/blog`,
      },
      {
        source: '/blog/:path+',
        destination: `${process.env.BLOG_DOMAIN}/blog/:path+`,
      },
      {
        source: '/blog-static/:path+',
        destination: `${process.env.BLOG_DOMAIN}/blog-static/:path+`,
      },
    ]
  },
}

export default nextConfig

注意:URL 路径在每个区域内必须唯一。两个区域不能同时服务 /blog

用代理路由

也可以用 Nginx、Varnish 等 HTTP 代理做路由。代理方式更灵活,比如可以根据 feature flag 动态决定路由目标:

export async function proxy(request) {
  const { pathname, search } = request.nextUrl
  if (pathname === '/your-path' && myFeatureFlag.isEnabled()) {
    return NextResponse.rewrite(`${rewriteDomain}${pathname}${search}`)
  }
}

区域间链接

跨区域的链接必须用 <a> 标签,不能用 <Link> 组件。因为 <Link> 会尝试做软导航和预加载,跨区时无效:

// 错误:跨区用 Link 会失效
<Link href="/dashboard">控制台</Link>

// 正确:跨区用 a 标签
<a href="/dashboard">控制台</a>

区域内导航还是推荐用 <Link>,享受软导航的性能优势。

代码共享

Monorepo

把多个区域放在同一个 monorepo 里,方便共享代码:

apps/
├── main/      # 主站
├── blog/      # 博客
└── dashboard/ # 后台
packages/
└── shared/    # 共享组件库

NPM 包

如果区域在不同仓库,可以用公共或私有 NPM 包共享代码。

Server Actions 跨域

多区域部署时,Server Actions 需要额外配置 allowedOrigins

// next.config.ts
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  experimental: {
    serverActions: {
      allowedOrigins: ['your-production-domain.com'],
    },
  },
}

export default nextConfig

因为用户看到的域名可能对应多个后端应用,需要明确允许跨域调用。

多租户架构

多租户是指一个应用为多个客户(租户)服务,每个租户有独立的数据和配置。

官方示例

Next.js 提供了 platforms-starter-kit 模板,展示了推荐的多租户架构。

常见实现方式

基于子域名

tenant1.example.com
tenant2.example.com

基于路径

example.com/tenant1
example.com/tenant2

基于自定义域名

tenant1.com -> 指向你的应用
tenant2.com -> 指向你的应用

租户识别

proxy.ts 中识别租户:

export function proxy(request: NextRequest) {
  const hostname = request.headers.get('host')
  // 根据 hostname 查询租户信息
  const tenant = await getTenantByHost(hostname)
  
  // 把租户信息存入请求头,供后续使用
  const requestHeaders = new Headers(request.headers)
  requestHeaders.set('x-tenant-id', tenant.id)
  
  return NextResponse.next({
    request: { headers: requestHeaders },
  })
}

数据隔离

// 所有查询都带上租户 ID
export async function getPosts(tenantId: string) {
  return db.select().from(posts).where(eq(posts.tenantId, tenantId))
}

租户级缓存

import { unstable_cache } from 'next/cache'

export const getCachedPosts = unstable_cache(
  async (tenantId: string) => {
    return await getPosts(tenantId)
  },
  ['posts'],
  {
    tags: (tenantId) => [`posts-${tenantId}`],
  }
)

最佳实践

  1. 按业务边界拆分区域:不同业务模块独立部署
  2. 区域内高内聚:频繁互动的页面放一起
  3. 共享登录态:用顶层 domain 的 cookie 共享认证
  4. 统一设计系统:跨区域的组件库保持一致
  5. 监控每个区域:独立追踪各区域的性能和错误

注意事项

  1. SEO 影响:跨区硬导航对 SEO 有一定影响,重要页面做好 SSR
  2. 首屏加载:每个区域首次访问需要完整加载
  3. 会话共享:确保 cookie domain 设置正确
  4. 错误隔离:一个区域的错误不应影响其他区域

多区域和多租户是大型应用的演进方向。早期不需要过度设计,但了解这些方案能在业务增长时做出正确的选择。

上一篇
监控与可观测性
下一篇
已经是最后一篇啦