はじめに
Next.js の App Router を使っていると、
動的ルート(例: /schools/[id]
)で以下のようなエラーに遭遇することがあります。
Error: used params.id. params should be awaited before using its properties.
このエラーの原因は、Next.js の新しい仕様で params
が Promise になることがあるため です。
本記事では エラーの原因と、その解決方法 について解説します。
原因
Next.js 15.1.6 以降の App Router では、動的ルートの params
が非同期(Promise になる場合がある) 仕様になりました。
そのため、以下のように params.id
に直接アクセスするとエラー になります。
間違ったコード例
params.id
に直接アクセスするとエラー
export default async function Page({ params }: { params: { id: string } }) {
const id = params.id; // ❌ ここでエラーが発生する可能性あり!
const data = await fetchData(id);
return <div>{data.name}</div>;
}
params は Promise かもしれない ので、params.id にすぐアクセスするとエラーになります。
対処
解決策は await を使って params を解決してから使うこと です。
修正後のコード例
✅ await を使って params を取得
export default async function Page(props: { params: Promise<{ id: string }> }) {
const resolvedParams = await props.params; // ✅ `params` を `await` してから使う
const id = resolvedParams.id;
const data = await fetchData(id);
return <div>{data.name}</div>;
}
これで params.id が未解決のまま参照されることがなくなり、エラーが解消 されます!
追記
Vercelでデプロイを実行したところ、params を await する際の ESLint エラーが発生しデプロイに失敗しました。
具体的には、params: { id: string } の型が Promise の可能性を考慮していないため、型エラーが発生していました。
エラー例 (Vercelデプロイ時)
ams: { id: string; }; children: ReactNode; }' does not satisfy the constraint 'LayoutProps'.
Types of property 'params' are incompatible.
Type '{ id: string; }' is missing the following properties from type 'Promise<any>': then, catch, finally, [Symbol.toStringTag]
修正
ESLint のエラーを防ぐために、型を Promise<{ id: string }> に変更 します。
こうすることで、ESLint に「params が Promise である可能性がある」と明示でき、エラーを防ぐことができます。