The shape of a page
A page.tsx exports a default React component. By default it's a Server Component, so it can be async. Server Components don't take many props — the framework injects route data via two specific props:
params: route parameters from[slug]-style segments.searchParams: query string parameters from the URL.
Both props are Promises in v15+
The big breaking change from v14 to v15: params and searchParams are Promises. You must await them. In Client Components, use React.use(params). The Promise wrap unblocks parallel rendering — nothing has to wait for params resolution before it starts.
Type helpers
Next.js publishes typed helpers under the next module entry. PageProps<'/blog/[slug]'> gives you a fully typed params based on the literal route path.
Treat params and searchParams as untrusted request input, not as convenient typed state. Await them, validate the values against the domain, and end missing-resource paths with notFound(). PageProps protects the names implied by the route literal; it does not prove that a slug exists or that a query value is allowed.
The Promise API is not ceremony for its own sake. It lets unrelated rendering work begin before route values have resolved. The wrong response is to hide the Promise behind an unsafe cast. Keep the asynchronous boundary visible where the framework hands the request to your page. Exercise the page with a valid path, a missing segment, repeated query keys, and a value outside the allowed set. Then rename [slug] to [postId] and confirm the generated type follows the folder. A passing happy path alone does not test the route contract.