【Next.js】middlewareを設置して404を偽装する [Techblog#5]

Next.js(App router)のmiddleware機能を利用して、特定ページにアクセスされたら404(Page Not Found)になるよう設定してみます。Cloudflareで404レスポンスを返すには別途対応が必要です

🎈

動作確認環境

  • Next.js: 14.2.3


Next.jsのmiddleware機能を利用して、ルーティングを設定してみます

特定のページにアクセスがあった場合に、非表示ページとして404を偽装したい時などに便利です


middleware.tsapp ディレクトリと同じ階層に配置します

src├── middleware.ts└── app/    ├── page.tsx    └── error/        └── 404/            └── page.tsx

例として /minaide とそれ以下の階層にアクセスがあった場合、404にルーティングをしたい場合は以下のように記述します

/error/404 に配置する404ページを別途設置する必要がありますrewrite メソッドで実現可能です 🎉

import { NextRequest } from 'next/server'export const middleware = async (req: NextRequest) => {  if (req.nextUrl.pathname.startsWith('/minaide')) {    return NextResponse.rewrite(`${req.nextUrl.origin}/error/404`, { status: 404 })  }  return NextResponse.next()}

NextResponse.next() は、リクエスト通りに処理を続けることを示します


📌

/error/404 を別途設置したくない場合

以下のCloudflare問題と同じ対応を取ることで、回避できます (若干ゴリ押しですが)




Cloudflareにデプロイした場合は、相性問題なのか404として返答がされない場合があります (ページは404が表示される)

ローカル上でビルドした場合は、問題なく404が返却されます

curl -I https://example.com/minaide
HTTP/2 200date: Mon, 20 May 2024 14:08:45 GMTcontent-type: text/html; charset=utf-8...

ちょっと気持ち悪いので、これを修正したい場合は、新たに NextResponse を生成することで対応できます

import { NextResponse, NextRequest } from 'next/server'export const middleware = async (req: NextRequest) => {  if (req.nextUrl.pathname.startsWith('/minaide')) {    const body = await (async () => {      try {        return await (await fetch(`${req.nextUrl.origin}/404`)).text()      } catch {        return '<h1>404 Not Found</h1>'      }    })()    const res = new NextResponse(body, {      status: 404,      headers: {        'Access-Control-Allow-Origin': '*',        'Cache-Control': 'public, max-age=0, must-revalidate',        'Content-Type': 'text/html; charset=utf8',        'X-Content-Type-Options': 'nosniff',        'X-Matched-Path': '/404',        'X-Robots-Tag': 'noindex',      },    })    return res  }  return NextResponse.next()}

404ページの取得などが若干ゴリ押しではありますが、これでCloudflareでも404が返却されるようになります 🎉

HTTP/2 404 date: Mon, 20 May 2024 14:20:56 GMTcontent-type: text/html; charset=utf8...

🐈

おわりに

環境変数と組み合わせれば、StagingとProductionで異なるルーティングを実現することも可能です 🐶


URLコピー
QRコード
X / Twitter
はてブ
支援 (GitHub Sponsors)
Folklore・Ⓒ 2021--2024 Koizumi