複数のNext.jsアプリケーションを同ドメインで動かす巨大なアプリケーションの作り方(カスタムサーバー)

1 min read読了の目安(約1500字

個人的な備忘録も兼ねて。

main.ts
import express from "express";
import next from "next";
import http from "http";

const bootstrap = async (): void => {
	const app = express();
	const firstApplication = next({
		dev: true,
		dir: path.resolve(__dirname, "./first")
	});
	const secondApplication = next({
		dev: true,
		dir: path.resolve(__dirname, "./second")
	});
	
	await secondApplication.prepare();
	const secondHandler = await secondApplication.getRequestHandler();
	app.all("/second", (req, res) => {
		secondHandler(req, res);
	});
	
	await firstApplication.prepare();
	const firstHandler = await firstApplication.getRequestHandler();
	app.get("/",(req, res) => {
		firstHandler(req, res);
	});
	app.get("/*", (req, res) => {
		firstHandler(req, res);
	});
	
	http.createServer(app).listen(3000, (err?: any) => {
		if (err instanceof Error) {
			throw err;
		}
		console.log(`Ready!`);
	});
};

bootstrap();
first/next.config.js
module.exports = {
	async rewrites() {
		return [
			{
				source: "/:path",
				destination: "/:path"
			},
			{
				source: "/second",
				destination: "/second"
			},
			{
				source: "/second/:path",
				destination: "/second/:path"
			}
		]
	}
};
second/next.config.js
module.exports = {
	basePath: "/second",
	assetPrefix: "/second"
}

main.tsをwebpackかなどでコンパイルして実行すれば/second以下はsecondディレクトリ以下のNext.jsプロジェクト、その他はfirstディレクトリ以下のNext.jsプロジェクトを使用できます。

Vercelなどを使用してSSGとしてホストする場合は公式にサンプルがあります。

https://nextjs.org/docs/advanced-features/multi-zones

以上です。