Fixing the "Types of property 'params' are incompatible" Issue in NextJS 15

Table of contents

NextJS is a huge framework in the web development industry in 2025. Lots of people using it for their application. Be it hobbyists, professionals, etc. One thing is for sure, when we build a dynamic web app, we will almost always encountering the use of params
.
The move from previous versions to Next 15 brings some unique challenges, especially when dealing with params
. As the saying goes, “Every change breaks someone’s workflow”. And today, that was exactly what happened to me 😂. Hence, I want to document it as a blog post for further reference for anyone who need it (might as well be future me imo).
TL;DR
type Params = Promise<{ slug: string }>;
The problem
Let’s say we develop a dynamic web app. Dynamic in here means we populate the app with dynamic data streams from the server (database, API, or such). As for me, I was in the middle of making two pages: blog
and blog/[id]
. You might have guessed that blog/[slug]
needs the slug
as a parameter to fetch the data from the API. My file is something like this:
blog/[slug]
page:
// NOTE: I only put in the conflicting lines.
...
const PostPage = async ({ params }: { params: { slug: string } }) => {
const post = await getPostBySlug(params.slug);
if (!post) {
return <div>Post not found</div>;
}
return (
<>
<Layout>
<div className="container mx-auto px-4 max-w-3xl">
...
and while this does work locally, it went full alarm once I pushed it to Vercel. The error was
Failed to compile.
app/blog/[slug]/page.tsx
Type error: Type '{ params: { slug: string; }; }' does not satisfy the constraint 'PageProps'.
Types of property 'params' are incompatible.
Type '{ slug: string; }' is missing the following properties from type 'Promise<any>': then, catch, finally, [Symbol.toStringTag]
First trial
After reading the error, I then trying to do something like this
// NOTE: I only put in the conflicting lines.
...
type PageProps = {
params: {
slug: string;
};
};
const PostPage = async ({ params }: PageProps) => {
const post = await getPostBySlug(params.slug);
if (!post) {
return <div>Post not found</div>;
}
return (
<>
<Layout>
<div className="container mx-auto px-4 max-w-3xl">
...
as you can see, I now throw in PageProps
as a type. Once again, everything works well in dev/local but then scream when pushed to Vercel. The dreaded error was still there.
The solution
Desperate times called for a Google search. With quick searches I then found this post https://github.com/vercel/next.js/discussions/71997
and within that post was this guy’s brilliant idea (shout out to ignatiosdev):
Intrigued by his idea, I then try this
...
type Params = Promise<{ slug: string }>;
const PostPage = async ({ params }: { params: Params }) => {
const { slug } = await params;
const post = await getPostBySlug(slug);
if (!post) {
return <div>Post not found</div>;
}
return (
<>
<Layout>
<div className="container mx-auto px-4 max-w-3xl">
...
aaand it works!
Now it works both in local and production env and nothing was broken no more. All needed to be done was adding type Params = Promise<{ slug: string }>;
before calling the params as an argument to the async function.
Conclusion
Initiate Params as a type Promise and only then you can call it to the async function. For further reference, I do suggest reading the NextJS documentation. But for now, that did the job for me so I will leave it there.
Hope this helps!
Let's have further discussion in the comment and bye for now 👋👋
Subscribe to my newsletter
Read articles from Justforvan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
