如何在单个Next.js项目中实现多子域名站点部署?
在Next.js中实现子域名对应独立页面目录的方案
方案一:用Next.js Middleware(Next.js 12+推荐)
Middleware能在请求到页面之前拦截处理,直接根据子域名重写路径到对应pages目录,完美适配你的需求。
- 在项目根目录新建
middleware.ts文件,写入以下逻辑:
import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' export function middleware(request: NextRequest) { const hostname = request.headers.get('host') || '' // 匹配主域名下的子域名(自动排除www) const subdomainMatch = hostname.match(/^([^\.]+)\.mydomain\.com$/) if (subdomainMatch) { const subdomain = subdomainMatch[1] // 把请求路径重写到对应子目录,比如 mysubdomain.mydomain.com/about → /mysubdomain/about const url = request.nextUrl.clone() url.pathname = `/${subdomain}${url.pathname}` return NextResponse.rewrite(url) } // 主域名请求直接放行 return NextResponse.next() } // 匹配所有路径的请求 export const config = { matcher: ['/:path*'], }
- 确保
next.config.js配置正确(不需要额外重写规则,保持默认即可):
/** @type {import('next').NextConfig} */ const nextConfig = {} module.exports = nextConfig
- 本地测试时,在系统hosts文件里加一行映射:
127.0.0.1 mysubdomain.mydomain.com,启动next dev就能直接访问子域名测试。
方案二:修正自定义server.ts逻辑
你之前试server.ts没成功,大概率是路由重写的逻辑没写对,以下是可运行的版本:
- 项目根目录新建
server.ts:
import { createServer } from 'http' import { parse } from 'url' import next from 'next' const dev = process.env.NODE_ENV !== 'production' const app = next({ dev }) const handle = app.getRequestHandler() app.prepare().then(() => { createServer((req, res) => { const parsedUrl = parse(req.url || '', true) const hostname = req.headers.host || '' // 解析子域名 const subdomainMatch = hostname.match(/^([^\.]+)\.mydomain\.com$/) if (subdomainMatch) { const subdomain = subdomainMatch[1] // 重写路径到对应pages子目录 parsedUrl.pathname = `/${subdomain}${parsedUrl.pathname}` } handle(req, res, parsedUrl) }).listen(3000, (err) => { if (err) throw err console.log('> Ready on http://localhost:3000') }) })
- 修改
package.json的启动脚本:
"scripts": { "dev": "ts-node server.ts", "build": "next build", "start": "NODE_ENV=production ts-node server.ts" }
- 安装依赖:
npm install ts-node @types/node --save-dev,本地测试同样需要配置hosts。
方案三:多pages目录+环境变量(部署时切换)
如果需要在部署阶段指定不同的pages目录,用环境变量就能实现,还能共享所有组件:
- 在
next.config.js里根据环境变量指定pages目录:
/** @type {import('next').NextConfig} */ const nextConfig = { pagesDir: process.env.NEXT_PAGES_DIR || 'src/pages', } module.exports = nextConfig
- 部署子域名站点时,通过环境变量指定目录:
NEXT_PAGES_DIR=src/pages/mysubdomain npm run build
这种方式适合每个子域名单独部署,但项目里的组件、工具类都能直接复用,适合CI/CD批量部署场景。
关键注意事项
- 组件复用:不管用哪种方案,都能直接从
src/components等公共目录导入组件,完全不用拆分项目。 - 生产部署:要在域名服务商那边把子域名解析到你的部署服务器/平台(比如Vercel、Netlify),同时在部署平台添加子域名的访问权限。
- 静态导出限制:如果用
next export生成静态文件,Middleware方案会受限,此时优先选自定义服务器或多pages目录方案。
内容的提问来源于stack exchange,提问作者Fabian
相关产品推荐
相关产品推荐

