開発ブログ

株式会社Nextatのスタッフがお送りする技術コラムメインのブログ。

電話でのお問合わせ 075-744-6842 ([月]-[金] 10:00〜17:00)

  1. top >
  2. 開発ブログ >
  3. Next.js >
  4. Next.js12 新規機能 【Middleware】を試してみた
no-image

Next.js12 新規機能 【Middleware】を試してみた

こんにちは、けいちゃんです。
私の住んでいる地域は先日梅雨入りしました。
連日雨の様子を見て通勤していた頃を思い出し、在宅勤務でよかったな、と痛感するこの頃です。

さて、今回は、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版とのことなので、正式リリースを待ちたいと思います。
TOPに戻る