サポートされていない言語コードの処理
問題
アプリケーションがURLパス(例:/en/、/fr/)を使用して言語を判定していますが、ユーザーは/xx/aboutのような任意の値を手動で入力できます。この値がサポートされている言語と一致しない場合、アプリケーションがクラッシュしたり、一般的なエラーを表示したり、翻訳されていないコンテンツを表示したりして、ユーザーを有効なエクスペリエンスに誘導できなくなる可能性があります。
解決策
ミドルウェアを使用して、すべての受信リクエストをインターセプトします。このミドルウェアは、URLから取得した言語コードを、サポートされている言語の確定リストと照合して検証します。コードがサポートされていない場合、リクエストはアプリケーションロジックに到達する前に「Not Found」ページに書き換えられます。
手順
1. サポートする言語を定義する
有効な言語コード(ロケール)のリストを保存するための中央設定ファイルを作成します。これにより、ミドルウェアやアプリの他の部分でリストを再利用できるようになります。
// i18n.config.ts
export const locales = ['en', 'es', 'fr'];
2. ミドルウェアファイルを作成する
プロジェクトのルート(またはsrc/ディレクトリ内)にmiddleware.tsという名前の新しいファイルを作成します。Next.jsはこのファイルを自動的に検出し、リクエスト時に実行します。
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { locales } from './i18n.config';
export function middleware(request: NextRequest) {
// Logic will go here in the next step
}
3. 検証ロジックを追加する
middleware関数内で、リクエストからpathnameを取得します。パスの最初のセグメント(例:/en/about内のen)をチェックし、それが有効でサポートされている言語であるかどうかを確認する必要があります。
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { locales } from './i18n.config';
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
// 1. Handle the root path separately
// (This will be handled by the next recipe: "Detecting a user's
// preferred language"). For now, we just let it pass.
if (pathname === '/') {
return NextResponse.next();
}
// 2. Extract the language code from the path
const langCode = pathname.split('/')[1];
// 3. Check if the language code is in our list
if (locales.includes(langCode)) {
// Language is valid, continue to the requested page
return NextResponse.next();
}
// 4. If the language is not valid, rewrite to a 404 page
// This keeps the invalid URL in the browser bar
const url = request.nextUrl.clone();
url.pathname = `/404`; // Assumes you have an app/404.tsx file
return NextResponse.rewrite(url);
}
このロジックはすべてのリクエストをチェックします。URLが/fr/aboutの場合、langCodeはfrであり、locales内に見つかるため、リクエストは続行されます。URLが/xx/aboutの場合、langCodeはxxであり、見つからないため、アプリが無効なリクエストを処理しようとすることなく、ユーザーには404ページが表示されます。
4. ミドルウェアマッチャーの設定
ミドルウェアをより効率的にするには、実行するパスを指定する必要があります。ページリクエストでは実行し、静的ファイルとAPIルートではスキップするようにします。
middleware.tsファイルの末尾にconfigオブジェクトを追加します。
// middleware.ts
// ... (the middleware function from above)
export const config = {
matcher: [
// Skip all paths that start with:
// - api (API routes)
// - _next/static (static files)
// - _next/image (image optimization files)
// - favicon.ico (favicon file)
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
};
この正規表現は、通常静的アセットやAPI呼び出しに使用されるパスを除くすべてのパスでミドルウェアを実行するように指示します。これにより、すべての画像、フォント、データリクエストで不要な検証が行われるのを防ぎます。