Next.js 15 動的ルートでの非同期 params 処理エラー解決法
問題概要
Next.js 15のApp Router(appディレクトリ)で動的ルートを使用する際、次のエラーが発生する問題が報告されています:
Error: Route "/[locale]" used `params.locale`. `params` should be awaited before using its properties.
このエラーは主に、[locale]
のような動的ルートセグメントを含むレイアウトやページコンポーネントで、params
オブジェクトを正しく処理できていない場合に発生します。
典型的な問題の発生箇所
export default async function RootLayout({
children,
params: { locale } // ここでエラーが発生
}: {
children: React.ReactNode;
params: { locale: string };
}) {
// コンポーネントロジック
}
エラー原因
Next.js 15では、動的ルートパラメータ(params
)が非同期APIとして変更されました。この変更により:
params
オブジェクトがPromiseでラップされた形式で渡される- 直接的な分割代入やプロパティアクセスが不可能に
await
キーワードによる解決が必要に
解決方法
基本的方法: paramsをawaitで待機
<code-group> <code-block title="layout.tsx" active> ```tsx export default async function RootLayout({ children, params // 分割代入せずに受け取る }: { children: React.ReactNode; params: Promise<{ locale: string }>; // Promise型を明示 }) { const { locale } = await params; // awaitで解決return ( <html lang={locale}> <body>{children}</body> </html> ); }
</code-block>
<code-block title="page.tsx">
```tsx
export default async function Home({
params
}: {
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
return (
<div>
<MainPicture locale={locale} />
</div>
);
}
APIルートでの対応例
export async function POST(
req: Request,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
// idを使用した処理
}
よくある落とし穴と回避策
1. 静的ファイル配置の問題
動的セグメントディレクトリ内にicon.png
などの静的ファイルが存在するだけでエラーが発生する場合があります:
app/
├── [lang]/
│ └── layout.tsx
- └── icon.png // エラー発生源
+
+ icon.png // 正しい位置に移動
2. TypeScript型定義の調整
従来の型定義を以下のように修正:
// 修正前
params: { locale: string };
// 修正後
params: Promise<{ locale: string }>;
3. 自動修正コマンドの利用
Next.js公式のcodemodで一部自動修正可能:
npx @next/codemod@canary next-async-request-api
実践的サンプルコード
import { TranslationsProvider } from "@/components/TranslationsProvider";
import initTranslations from "../i18n";
export default async function LocaleLayout({
children,
params,
}: {
children: React.ReactNode;
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
const { resources } = await initTranslations(locale, ["common"]);
return (
<html lang={locale}>
<TranslationsProvider resources={resources} locale={locale}>
<body>{children}</body>
</TranslationsProvider>
</html>
);
}
パフォーマンス最適化
generateStaticParams
と併用することで、事前生成と動的処理を両立可能:
export function generateStaticParams() {
return i18nConfig.locales.map((locale) => ({ locale }));
}
なぜこの変更が必要か?
Next.js 15では、動的レンダリングパフォーマンスの最適化のため、ルートパラメータの取得プロセスが非同期化されました:
- ストリーミングSSRの最適化
- 静的生成と動的レンダリングのシームレスな統合
- エッジランタイムでの互換性向上
補足リソース
正しい非同期処理を実装することで、Next.js 15のパフォーマンス改善を享受しつつ、国際化対応など動的ルートを必要とする機能を安定して動作させられます。