While trying to add generateMetadata
to the layout.tsx
in the dynamic route under the blog
dir, I bumped into this error:
Type error: Type 'Props' does not satisfy the constraint 'LayoutProps' .
Types of property 'params' are incompatible.
Type 'Params' is missing the following properties from type Promise<any?: then, catch, finally, [Symbol.toStringTag]
This issue is actually part of a breaking change in Next.js 15.
Here’s how to fix it:
To fix this, update the params
type to be a Promise
and use await
to resolve it inside the function.
import type { Metadata } from "next"
// make this a promise
interface Props {
params: Promise<{ slug?: string }>;
}
export async function generateMetadata({ params}: Props): Promise<Metadata> {
const { slug } = await params; //await here
}
Why did this issue happen?
This happened because Next.js 15 made params
asynchronous in certain functions like generateMetadata
. That means params
is no more a plain object, it's now a promise that needs to be awaited.
In your original code, you probably treated params
like a regular object, but Next.js 15 now expects it to be a Promise
that resolves to an object, so TypeScript throws an error. It's complaining that your params
is missing properties that come with a Promise (like .then
, .catch
, etc.).
So now changing params
to a Promise
will match what Next.js 15 expects.
Why did Next.js 15 add this change?
Next.js is changing some features (like cookies
, headers
, params
, and searchParams
) to work asynchronously. Usually, when someone visits a page, the server waits for the request before it generates and sends back the content for that page. This means the server typically doesn't render the page until it gets the request and any associated data (like parameters or cookies).
Since not all parts depend on the request data, the server no longer has to wait before rendering. And now the sever can prepare earlier and only wait when it really needs that data. Read more about this on Vercel’s website.
Top comments (0)