Next.js12 新規機能 【Middleware】を試してみた
こんにちは、けいちゃんです。
私の住んでいる地域は先日梅雨入りしました。
連日雨の様子を見て通勤していた頃を思い出し、在宅勤務でよかったな、と痛感するこの頃です。
さて、今回は、Next.js Version12でBeta版としてリリースされた新機能、Middlewareの記事です。
https://nextjs.org/docs/advanced-features/middleware
/pages ディレクトリ直下に _middleware.js(ts) ファイルを配置した場合、
また、 _middleware.js(ts) ファイルは /pages ディレクトリ直下以外にも配置することが可能です。
その場合は、階層の浅い方から順にコードが実行されます。
ログイン認証やFeature flagなど、全てのページで同様のロジックを共有する際に役立ちそうですね。
version12以降であればOKです。
package.json
/pages/_middleware.ts
/pages/_middleware.ts
ログイン認証を行わないページを指定したり、Basic認証を導入したり、許可していないIPからのアクセスをブロックしたり、 公式ドキュメント には他にも様々なsampleが紹介されています。
https://github.com/vercel/examples/tree/main/edge-functions
今はBeta版とのことなので、正式リリースを待ちたいと思います。
私の住んでいる地域は先日梅雨入りしました。
連日雨の様子を見て通勤していた頃を思い出し、在宅勤務でよかったな、と痛感するこの頃です。
さて、今回は、Next.js Version12でBeta版としてリリースされた新機能、Middlewareの記事です。
環境とソフトウェアのバージョン
- OS: macOS Monterey 12.4
- Next.js: 12.1.6
- Node: 16.13.1
Middlewareとは
公式ドキュメントは以下です。https://nextjs.org/docs/advanced-features/middleware
/pages ディレクトリ直下に _middleware.js(ts) ファイルを配置した場合、
/pages
ディレクトリ以下の全てのページでリクエスト完了前に _middleware.js(ts) のコードが実行されます。また、 _middleware.js(ts) ファイルは /pages ディレクトリ直下以外にも配置することが可能です。
その場合は、階層の浅い方から順にコードが実行されます。
- package.json
- /pages
_middleware.ts # 最初に実行
index.tsx
- /about
_middleware.ts # 2番目に実行
about.tsx
- /teams
_middleware.ts # 3番目に実行
teams.tsx
公式ドキュメントに記載の例では、以下のような使い方ができるようです。- Authentication
- Bot protection
- Redirects and rewrites
- Handling unsupported browsers
- Feature flags and A/B tests
- Advanced i18n routing requirements
ログイン認証やFeature flagなど、全てのページで同様のロジックを共有する際に役立ちそうですね。
Middlewareの型定義について
型定義は以下の通りです。
import type { NextFetchEvent } from 'next/server'
import type { NextRequest } from 'next/server'
export type Middleware = (
request: NextRequest,
event: NextFetchEvent
) => Promise<Response | undefined> | Response | undefined
リクエストとFetchイベントを受け取り、レスポンスを返すまたはなにも返さない関数となっています。ソースコードの作成
では、ソースコードを作成して実際に使い方を見ていきましょう。最新版のNext.jsのインストール
# npm
npm install next@latest
# yarn
yarn add next@latest
package.json で、最新版かを確認します。version12以降であればOKです。
package.json
{
"name": "name",
"version": "0.1.0",
.
.
},
"dependencies": {
.
.
"next": "^12.1.6",
.
.
}
}
_middleware.js(ts) ファイルの作成
example1
クエリパラメータをチェックして、許可されていないパラメータの場合はリダイレクトする。/pages/_middleware.ts
import { NextRequest, NextResponse } from 'next/server'
const allowedParams: string[] = ['allowed'] // 許可するパラメータの配列
export function middleware(req: NextRequest) {
const url = req.nextUrl
let isInvalid = false
url.searchParams.forEach((_, key) => {
if (!allowedParams.includes(key)) {
url.searchParams.delete(key)
isInvalid = true
}
})
if (isInvalid) {
return NextResponse.redirect(url)
// URLはリクエストされたURLのままで、表示する画面のみ変更したい場合は以下
// return NextResponse.rewrite(url)
}
}
example2
リクエストURLのpathを許可していない場合はHTTPステータス404のレスポンスを返却する。/pages/_middleware.ts
import { NextRequest, NextResponse } from 'next/server'
const rejectPaths: string[] = ['/about', '/teams'] // 拒否するpathの配列
export function middleware(req: NextRequest) {
const url = req.nextUrl
if (rejectPaths.includes(url.pathname)) {
return new Response(null, { status: 404 })
}
}
最後に
Middleware には他にも様々な使い方がありました。ログイン認証を行わないページを指定したり、Basic認証を導入したり、許可していないIPからのアクセスをブロックしたり、 公式ドキュメント には他にも様々なsampleが紹介されています。
https://github.com/vercel/examples/tree/main/edge-functions
今はBeta版とのことなので、正式リリースを待ちたいと思います。