Next.js(App router) の middleware 機能を利用して、特定ページにアクセスされたら 404(Page Not Found) になるよう設定してみます
動作確認環境
Next.js: 14.2.3 (App router)
Next.jsのmiddleware機能を利用して、ルーティングを設定してみます
特定のページにアクセスがあった場合に、非表示ページとして404を偽装したい時などに便利です
middleware.ts は app ディレクトリと同じ階層に配置します
src├── middleware.ts└── app/└── page.tsx└── not-found.tsx
例として /minaide とそれ以下の階層にアクセスがあった場合、404にルーティングをしたい場合は以下のように記述します
import { NextRequest } from 'next/server'export const middleware = async (req: NextRequest) => {if (req.nextUrl.pathname.startsWith('/minaide')) {return NextResponse.rewrite(`${req.nextUrl.origin}/404`, { status: 404 })}return NextResponse.next()}
NextResponse.next() は、リクエスト通りに処理を続けることを示します
Cloudflareにデプロイした場合は、相性問題なのか404として返答がされない場合があります (ページは404が表示される)
ローカル上でビルドした場合は、問題なく404が返却されます
2024年9月30日時点では rewrite でも問題なく 404 が返却されるようになっていました。以降の対応は必要ないです
curl -I https://example.com/minaideHTTP/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 404date: Mon, 20 May 2024 14:20:56 GMTcontent-type: text/html; charset=utf8...
おわりに
環境変数と組み合わせれば、StagingとProductionで異なるルーティングを実現することも可能です 🐶
Middleware を利用する方は、無駄なエッジ使用を減らすために、こちらの記事も参考にどうぞ ⭐