NextRequest と NextResponse

next/server は、ミドルウェアエッジAPIルート で使用するサーバー専用ヘルパーを提供します。

NextRequest

NextRequest オブジェクトは、ネイティブの Request インターフェースを拡張したもので、以下の追加メソッドとプロパティを持ちます:

  • cookies - リクエストから取得したクッキーを含む RequestCookies インスタンス。リクエストの Cookie ヘッダーを読み取り/変更します。ミドルウェアでのクッキー使用 も参照してください。

    • get - クッキーの name を受け取り、namevalue を含むオブジェクトを返すメソッド。name のクッキーが見つからない場合は undefined を返します。複数のクッキーが一致する場合、最初の一致のみを返します。
    • getAll - get と似ていますが、一致する name のすべてのクッキーのリストを返します。name が指定されていない場合は、利用可能なすべてのクッキーを返します。
    • set - W3C CookieStore API 仕様で定義されている CookieListItem のプロパティを持つオブジェクトを受け取るメソッド。
    • delete - クッキーの name または名前のリストを受け取り、一致する名前のクッキーを削除します。削除された場合は true、削除されなかった場合は false を返します。
    • has - クッキーの name を受け取り、クッキーが存在するかどうかに基づいて boolean を返します(存在する場合は true、存在しない場合は false)。
    • clear - 引数を取らず、Cookie ヘッダーを効果的に削除します。
  • nextUrl: pathnamebasePathtrailingSlashi18n などのNext.js固有のプロパティにアクセスできる拡張された解析済みURLオブジェクトを含みます。以下のプロパティを含みます:

    • basePath (string)
    • buildId (string || undefined)
    • defaultLocale (string || undefined)
    • domainLocale
      • defaultLocale: (string)
      • domain: (string)
      • http: (boolean || undefined)
      • locales: (string[] || undefined)
    • locale (string || undefined)
    • url (URL)
  • ip: (string || undefined) - リクエストのIPアドレスを含みます。この情報はホスティングプラットフォームによって提供されます。

  • geo - リクエストの地理的位置情報を含みます。この情報はホスティングプラットフォームによって提供されます。以下のプロパティを含みます:

    • city (string || undefined)
    • country (string || undefined)
    • region (string || undefined)
    • latitude (string || undefined)
    • longitude (string || undefined)

NextRequest オブジェクトは、ネイティブの Request インターフェースの直接の代替として使用でき、リクエストの操作方法をより詳細に制御できます。

NextRequestnext/server からインポートできます:

import type { NextRequest } from 'next/server'

NextFetchEvent

NextFetchEvent オブジェクトは、ネイティブの FetchEvent オブジェクトを拡張し、waitUntil() メソッドを含みます。

waitUntil() メソッドは、他のバックグラウンド作業がある場合に関数の実行を延長するために使用できます。

import { NextResponse } from 'next/server'
import type { NextFetchEvent, NextRequest } from 'next/server'

export function middleware(req: NextRequest, event: NextFetchEvent) {
  event.waitUntil(
    fetch('https://my-analytics-platform.com', {
      method: 'POST',
      body: JSON.stringify({ pathname: req.nextUrl.pathname }),
    })
  )

  return NextResponse.next()
}

NextFetchEvent オブジェクトは next/server からインポートできます:

import type { NextFetchEvent } from 'next/server'

NextResponse

NextResponse クラスは、ネイティブの Response インターフェースを拡張し、以下を含みます:

パブリックメソッド

パブリックメソッドは NextResponse クラスのインスタンスで利用可能です。使用例に応じて、インスタンスを作成して変数に割り当て、以下のパブリックメソッドにアクセスできます:

  • cookies - レスポンスのクッキーを含む ResponseCookies インスタンス。レスポンスの Set-Cookie ヘッダーを読み取り/変更します。ミドルウェアでのクッキー使用 も参照してください。
    • get - クッキーの name を受け取り、namevalue を含むオブジェクトを返すメソッド。name のクッキーが見つからない場合は undefined を返します。複数のクッキーが一致する場合、最初の一致のみを返します。
    • getAll - get と似ていますが、一致する name のすべてのクッキーのリストを返します。name が指定されていない場合は、利用可能なすべてのクッキーを返します。
    • set - W3C CookieStore API 仕様で定義されている CookieListItem のプロパティを持つオブジェクトを受け取るメソッド。
    • delete - クッキーの name または名前のリストを受け取り、一致する名前のクッキーを削除します。削除された場合は true、削除されなかった場合は false を返します。

静的メソッド

以下の静的メソッドは NextResponse クラスで直接利用可能です:

  • redirect() - リダイレクトが設定された NextResponse を返します
  • rewrite() - リライトが設定された NextResponse を返します
  • next() - ミドルウェアチェーンを継続する NextResponse を返します

上記のメソッドを使用するには、返された NextResponse オブジェクトを返す必要がありますNextResponsenext/server からインポートできます:

import { NextResponse } from 'next/server'

userAgent

userAgent ヘルパーを使用すると、リクエストからユーザーエージェントオブジェクトを操作できます。これはネイティブの Request オブジェクトから抽象化されており、オプトイン機能です。以下のプロパティを持ちます:

  • isBot: (boolean) リクエストが既知のボットからのものかどうか
  • browser
    • name: (string || undefined) ブラウザの名前
    • version: (string || undefined) 動的に決定されるブラウザのバージョン
  • device
    • model: (string || undefined) 動的に決定されるデバイスのモデル
    • type: (string || undefined) ブラウザのタイプで、以下のいずれかの値: consolemobiletabletsmarttvwearableembedded、または undefined
    • vendor: (string || undefined) 動的に決定されるデバイスのベンダー
  • engine
    • name: (string || undefined) ブラウザエンジンの名前で、以下のいずれかの値: AmayaBlinkEdgeHTMLFlowGeckoGoannaiCabKHTMLLinksLynxNetFrontNetSurfPrestoTasmanTridentw3mWebKit または undefined
    • version: (string || undefined) 動的に決定されるブラウザエンジンのバージョン、または undefined
  • os
    • name: (string || undefined) OSの名前、undefined の場合あり
    • version: (string || undefined) 動的に決定されるOSのバージョン、または undefined
  • cpu
    • architecture: (string || undefined) CPUのアーキテクチャで、以下のいずれかの値: 68kamd64armarm64armhfavria32ia64irixirix64mipsmips64pa-riscppcsparcsparc64 または undefined

userAgentnext/server からインポートできます:

import { userAgent } from 'next/server'
import { NextRequest, NextResponse, userAgent } from 'next/server'

export function middleware(request: NextRequest) {
  const url = request.nextUrl
  const { device } = userAgent(request)
  const viewport = device.type === 'mobile' ? 'mobile' : 'desktop'
  url.searchParams.set('viewport', viewport)
  return NextResponse.rewrite(url)
}

FAQ

redirect が 307 と 308 を使用する理由

redirect() を使用すると、一時リダイレクトには 307、恒久リダイレクトには 308 が使用されることに気付くかもしれません。伝統的に、一時リダイレクトには 302、恒久リダイレクトには 301 が使用されていましたが、多くのブラウザは 302 を使用する場合、元のリクエストメソッドに関係なく、リダイレクトのリクエストメソッドを POST から GET に変更していました。

/users から /people へのリダイレクトの例を考えます。新しいユーザーを作成するために /usersPOST リクエストを送信し、302 一時リダイレクトに従う場合、リクエストメソッドは POST から GET に変更されます。これは理にかなっていません。新しいユーザーを作成するには、GET リクエストではなく POST リクエストを /people に送信する必要があります。

307 ステータスコードの導入により、リクエストメソッドが POST として保持されるようになりました。

  • 302 - 一時リダイレクト、リクエストメソッドを POST から GET に変更
  • 307 - 一時リダイレクト、リクエストメソッドを POST として保持

redirect() メソッドは、デフォルトで 302 一時リダイレクトではなく 307 を使用するため、リクエストは常に POST リクエストとして保持されます。

POST リクエストに対して GET レスポンスを引き起こしたい場合は、303 を使用してください。

HTTPリダイレクトについてさらに学ぶ

環境変数にアクセスする方法

process.env を使用して、Edgeミドルウェアから環境変数にアクセスできます。これらは next build 時に評価されます:

動作する例動作しない例
console.log(process.env.MY_ENV_VARIABLE)const getEnv = name => process.env[name]
const { MY_ENV_VARIABLE } = process.env
const { "MY-ENV-VARIABLE": MY_ENV_VARIABLE } = process.env