本記事のゴール
元々MoldSpoon Inc. のWebサイトが動いているNext.jsプロジェクトの下に、さらにもう一つ、Next.jsプロジェクトを作ってブログとして配信したいと考えました。
- moldspoon.jp/blog 以下の全てのリクエストは子プロジェクト(ブログ)で補足
- moldspoon.jp/ 以下の全てのリクエストは親プロジェクトで補足
作業
公式ドキュメントをあたったところ、rewriteという方法があるようです。
以下のように、別途Vercelにデプロイしているプロジェクトの固定ドメインにもリンクが貼れるようです。
vercel.json
{
"rewrites": [
{
"source": "/blog",
"destination": "https://moldspoon-blog.vercel.app/blog/blog"
},
{
"source": "/blog/:match+",
"destination": "https://moldspoon-blog.vercel.app/blog/:match+"
}
]
}
こちらを親プロジェクトに vercel.json
というファイル名でプロジェクトルート直下に作成。
続いて、子プロジェクトの next.config.js
に以下の設定を追加します。
(私は/blog以下にデプロイしたいのでそうしました)
next.config.js
const isProd = process.env.NODE_ENV === 'production';
const cdnPrefix = isProd ? '/blog' : '';
if (isProd && cdnPrefix) {
console.log(`> You have customized the CDN prefix: ${cdnPrefix}.\n`);
}
const withMDX = require('@next/mdx')({
extension: /\.(md|mdx)?$/,
options: {
rehypePlugins: [require('@mapbox/rehype-prism'), require('rehype-join-line')],
},
});
/** @type {import('next').NextConfig} */
const nextConfig = {
basePath: '/blog',
assetPrefix: '/blog',
async rewrites() {
return [
{
source: "/blog",
destination: "/blog/blog",
},
{
source: "/blog/api/:path*",
destination: "/api/:path*",
},
{
source: "/blog/images/:query*",
destination: '/_next/image/:query*'
},
{
source: "/blog/_next/:path*",
destination: "/_next/:path*",
},
]
},
pageExtensions: ['jsx', 'js', 'mdx', 'md', 'ts', 'tsx'],
generateEtags: false,
poweredByHeader: false,
env: {
VERSION: require('./package.json').version,
},
redirects() {
return [];
},
};
module.exports = withMDX(nextConfig);
rewrites
の各設定がないと、
- https://moldspoon-blog.vercel.app/blog にリクエストした途端リダイレクトループ(308ステータス)に陥る (/blog => /blog/ => /blog とループする)
- Javascriptファイルへのパスが疎通せず、画面が真っ白になる(UIの描画がされない)ので注意してください。
これで、
https://moldspoon.jp/blog => https://moldspoon-blog.vercel.app/blog
に転送ができるようになりました。リダイレクトでないので、遷移が1つ増えるとかもないはず...。
ポイントとしては、子プロジェクトのvercelドメインで、サブディレクトリのパスがついた状態で 遷移できるか否かをチェックすることが肝要です。上記例だと、
- https://moldspoon-blog.vercel.app/blog 以下で全URLが見れるか(TOPしか
rewrite
が効いていない可能性がある) - react routerで遷移ができていても、URLの転送が効くかは別なので、その観点でも各ページでリロードして確認する
が作業完了までに必要になると思いました。
まとめ
大体の流れは以下でした。nginxやapacheのproxyと一緒で、リダイレクト系はどうしてもハマる時はハマっちゃいますね...
- 親プロジェクトのvercel.jsonに
rewrite()
設定を追加 - 子プロジェクトのnext.config.jsに
basePath
assetPrefix
rewrite()
を追加 - 両方のプロジェクトをデプロイ
monorepoで管理するという方法もあったのですが、今回は大きなプロジェクトではないのであまり難しく考えずに 簡単な方を選んでいます。