Featured image of post Next.js Middleware:ルーティング、認証、エッジコンピューティング Featured image of post Next.js Middleware:ルーティング、認証、エッジコンピューティング

Next.js Middleware:ルーティング、認証、エッジコンピューティング

Next.jsのMiddlewareを詳解。ルーティング制御、認証処理、エッジコンピューティング、ジオロケーション、A/Bテスト、そしてEdge Runtimeの制約まで実践的に解説します。

はじめに

Next.js Middlewareはすべてのリクエストの前に実行され、Edgeまたはサーバーレスリージョンで動作します。プロジェクトルートのmiddleware.tsファイルがリクエストをインターセプトし、ルートに到達する前にリダイレクト、リライト、ヘッダー操作、認証チェックを実行できます。

Middlewareはページレンダリング前の高速なエッジベースの判断に最適です。デフォルトで静的アセットや_next/staticでは実行されません。

基本構造

MiddlewareファイルはNextRequestを受け取りNextResponseを返す関数と、実行パスを定義するconfigオブジェクトをエクスポートします。

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function middleware(request: NextRequest) {
  console.log(`Request: ${request.nextUrl.pathname}`);
  return NextResponse.next();
}

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
};

matcher設定はpath-to-regexp構文と否定先読みを使用して静的ファイルを除外します。


認証と認可

Middlewareでの認証処理は、単一責任の原則に従い、ページ遷移時のちらつきを防ぐため、ページごとのチェックよりも優れています。

export function middleware(request: NextRequest) {
  const token = request.cookies.get("session")?.value;
  const { pathname } = request.nextUrl;

  if (!token && pathname.startsWith("/dashboard")) {
    return NextResponse.redirect(new URL("/login", request.url));
  }

  if (token && pathname.startsWith("/login")) {
    return NextResponse.redirect(new URL("/dashboard", request.url));
  }

  return NextResponse.next();
}

ロールベースアクセスではJWTをデコードしてユーザーのロールを確認します。NextAuth.js、Clerk、Auth0はMiddlewareヘルパーを提供しています。


リクエストのリライトとリダイレクト

Middlewareはリライトとリダイレクトの2種類のURL操作をサポートします。リライトはブラウザのURLを変えずに異なるコンテンツを配信し、リダイレクトはURLを変更します。

export function middleware(request: NextRequest) {
  const { pathname, hostname } = request.nextUrl;

  const tenant = hostname.split(".")[0];
  if (tenant && tenant !== "www") {
    request.nextUrl.pathname = `/${tenant}${pathname}`;
    return NextResponse.rewrite(request.nextUrl);
  }
}

地域別ランディングページ、フィーチャーゲート、マルチテナントルーティングに活用できます。


ジオロケーションとパーソナライゼーション

Edge Middlewareはrequest.geoを通じて都市、国、地域、緯度、経度のデータを提供します。

export function middleware(request: NextRequest) {
  const { country } = request.geo;
  const { pathname } = request.nextUrl;

  if (["DE", "FR", "IT", "ES", "NL"].includes(country) && !pathname.startsWith("/gdpr")) {
    return NextResponse.redirect(new URL("/gdpr", request.url));
  }

  return NextResponse.next();
}

地域別価格設定、コンテンツローカライゼーション、GDPR同意ルーティングに実践的に活用できます。


Edge Runtimeの制約

MiddlewareはEdge Runtimeで動作し、以下の重要な制約があります。

制約詳細
Node.js API利用不可(fs、crypto、pathなど)
最大実行時間30秒(1秒未満を目標)
バンドルサイズ1 MB制限
データベース直接接続不可。APIルートを使用

Middlewareのロジックは軽量に保ち、重い処理はAPIルートやサーバーコンポーネントに委譲します。


まとめ

Middlewareは認証、リダイレクト、URLリライトなどの高速なエッジベースの判断に使用します。すべてのマッチングリクエストで実行されるため、ロジックはシンプルに保ち、matcher設定を優先してパフォーマンスを最適化してください。