🐾
Next.jsのmiddlewareを本番と開発で切り替える
背景
- middleware.tsを本番と開発環境で別の内容にする必要があった
- 今までは開発環境のBasic認証にのみ使っていた。新たにリダイレクトの処理を入れるため、middlewareを環境によって分ける必要が出てきた
- 本番環境でのmiddlewareの発火を抑えることも課題だったのでmatcherの記述も追加した
課題
- middleware.tsは1ファイルしかデプロイできない
-
matcher
を開発と本番で切り替えたいが、process.env.NODE_ENV
のような環境による切り替えができない
解決法
-
middleware.ts
とmiddleware-for-production.ts
を分けて管理 - 本番ビルド時のみ
for-production
をmiddleware.ts
にコピーして差し替え
.github/workflows/deploy.yml
- name: Replace middleware.ts for Production
if: ${{ inputs.production == true }}
run: |
rm src/middleware.ts
cp src/middleware-for-production.ts src/middleware.ts
matcherの工夫
- 開発版(全体にマッチ)
開発環境ではBasic認証をサイト全体にかけるため、全体にマッチする書き方にする。
middleware.ts
export const config = {
matcher: [
"/((?!api|_next/static|_next/image|favicon.ico).*)",
],
}
- 本番版(検索クエリがある場合のみマッチ)
本番環境では、検索ページ/search
において、特定の検索条件が存在する場合のみmiddlewareを発火させたい要件があった。
そのため、matcherを以下のように記述した。
middleware-for-production.ts
export const config = {
matcher: [
{ source: "/search(.*)", has: [{ type: "query", key: "category" }] },
{ source: "/search(.*)", has: [{ type: "query", key: "location" }] },
{ source: "/search(.*)", has: [{ type: "query", key: "type" }] },
],
};
まとめ
- middlewareはファイルを分けて管理することで、開発・本番で挙動を変えられる
- matcherの設定は、クエリパラメータの有無まで柔軟に制御できる
- matcherを設定することによりmiddlewareの発火を最低限に抑えることができる
- GitHub Actionsで差し替えを自動化すれば安全に運用可能

ちょっと株式会社(chot-inc.com)のエンジニアブログです。 フロントエンドエンジニア募集中! カジュアル面接申し込みはこちらから chot-inc.com/recruit/iuj62owig
Discussion