本記事のゴール

元々MoldSpoon Inc. のWebサイトが動いているNext.jsプロジェクトの下に、さらにもう一つ、Next.jsプロジェクトを作ってブログとして配信したいと考えました。

作業

公式ドキュメントをあたったところ、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.jp/blog => https://moldspoon-blog.vercel.app/blog

に転送ができるようになりました。リダイレクトでないので、遷移が1つ増えるとかもないはず...。

ポイントとしては、子プロジェクトのvercelドメインで、サブディレクトリのパスがついた状態で 遷移できるか否かをチェックすることが肝要です。上記例だと、

が作業完了までに必要になると思いました。

まとめ

大体の流れは以下でした。nginxやapacheのproxyと一緒で、リダイレクト系はどうしてもハマる時はハマっちゃいますね...

monorepoで管理するという方法もあったのですが、今回は大きなプロジェクトではないのであまり難しく考えずに 簡単な方を選んでいます。