Do Next.js App Router Pages Accept Regular Props?

A quick dive into why Next.js App Router page components don't accept arbitrary props like regular React components, with a blog post example and code to show how to work with route-specific props (params, searchParams). Explains the framework's design for efficiency and offers tips for managing data flow.
When building with Next.js, especially after the introduction of the App Router (app/
directory in Next.js 13+), many developers bump into a confusing question:
👉 Why can’t I pass regular props into a page component like I do with normal React components?
It feels strange at first, but once you understand the reasoning, it actually makes a lot of sense. Let’s break it down.
Pages in the App Router Are Special
In a standard React project, you can create a component and pass it any props you like:
tsxfunction Card({ title, description }) { return ( <div> <h2>{title}</h2> <p>{description}</p> </div> ); } // Usage <Card title="Hello" description="World" />
Simple, right?
But in the Next.js App Router, page.tsx
files don’t work this way. A page is not a “regular” component you call yourself. Instead, it’s an entry point that Next.js calls automatically when a user visits a route. Because of this, Next.js controls what props your page gets.
What Props Do Pages Actually Get?
By default, pages in the App Router only receive special props from Next.js:
params
→ dynamic route segments (from[id]
,[slug]
, etc.)searchParams
→ query string values (from?filter=active
, etc.)
For example:
tsx// app/blog/[slug]/page.tsx export default function BlogPostPage({ params, searchParams }: { params: { slug: string }; searchParams: { [key: string]: string | string[] | undefined }; }) { return ( <div> <h1>Blog Post: {params.slug}</h1> <p>Filter: {searchParams.filter}</p> </div> ); }
Here, Next.js automatically injects the slug
and any query parameters. You don’t decide those props—Next.js does.
Why This Design Choice?
The App Router is all about routing and data-fetching conventions.
- Each
page.tsx
represents a unique route. - Next.js needs to know how to fetch, render, and cache that page.
- If you could pass arbitrary props to a page, the routing system would lose predictability and caching efficiency.
In short: pages are routes, not just components.
How Do You Use “Regular Props” Then?
If you still want to use custom props, the solution is simple: delegate them to child components.
For example:
tsx// app/blog/[slug]/page.tsx import BlogPost from "@/components/BlogPost"; export default function BlogPostPage({ params }: { params: { slug: string } }) { const post = { title: "Hello World", content: "This is a demo." }; // Pass props to a normal component return <BlogPost title={post.title} content={post.content} />; }
And your child component can accept props normally:
tsxtype BlogPostProps = { title: string; content: string; }; function BlogPost({ title, content }: BlogPostProps) { return ( <article> <h1>{title}</h1> <p>{content}</p> </article> ); } export default BlogPost;
This way, you still get the power of props—just not at the page.tsx
level.
Key Takeaways
- Page components in the App Router don’t take regular props.
- They only receive
params
andsearchParams
(andchildren
in layouts). - If you need arbitrary props, use child components—they behave like normal React components.
- Think of pages as routes, not as general-purpose components.
✅ Conclusion: When working in Next.js App Router, remember: pages are tied to routes, not to your component tree. Treat them as entry points, and push your flexible logic down into child components. Once you adopt this mindset, the system feels cleaner, more predictable, and easier to scale.