Skip to content

Next.js Pages

A "page" is the unique content rendered for one specific route. This lesson focuses specifically on page.tsx — what it's responsible for, what props it receives, and how it differs from layouts and other special files.

What Exactly Is a Page?

A page is a React component, default-exported from a file named exactly page.tsx, that renders the content unique to one route. Unlike a layout, a page does not persist across navigation to a sibling route — visiting a different page always unmounts the previous one and mounts the new one.

Pages automatically receive params (dynamic route values) and searchParams (parsed query string values) as props from Next.js, without you needing to read window.location or use any client-side hook.

// app/search/page.tsx
export default function SearchPage({
  searchParams,
}: {
  searchParams: { q?: string };
}) {
  return <h1>Results for: {searchParams.q ?? "(nothing yet)"}</h1>;
}

Visiting /search?q=nextjs renders "Results for: nextjs" — searchParams is provided automatically, no client-side parsing required.

Props a Page Component Receives

export default function Page({
  params,          // dynamic route segments, e.g. { id: "42" }
  searchParams,    // parsed query string, e.g. { sort: "asc" }
}: {
  params: Record<string, string>;
  searchParams: Record<string, string | string[] | undefined>;
}) { /* ... */ }
  • params reflects any dynamic segments ([id], [...slug]) in the page's own route path.
  • searchParams reflects the query string and is only available on page.tsx, not layout.tsx.
  • Both props are provided automatically by Next.js — no import or hook is required to read them.
  • A page that uses only these props (and no client interactivity) stays a Server Component by default.

Pages Cheat Sheet

What makes a file a page, and what it receives.

Aspect Detail
Required filename page.tsx (or .jsx)
Required export Default export returning JSX
Receives params Yes, for dynamic segments
Receives searchParams Yes, parsed from the query string
Persists across navigation No — always remounts for a new route
Can export metadata Yes, for SEO tags

Pages vs. Layouts

It's easy to conflate pages and layouts since both are just React components living in route folders, but their responsibilities are distinct: a page renders the content unique to its exact route, while a layout renders UI shared across that route and everything nested beneath it.

Aspect page.tsx layout.tsx
Receives searchParams Yes No
Persists across sibling navigation No Yes
Required to make a route reachable Yes No

Pages as Async Server Components

Because pages are Server Components by default, marking a page's function async lets it await data directly, combining routing, data fetching, and rendering into a single, readable function.

// app/blog/[slug]/page.tsx
export default async function BlogPostPage({
  params,
}: {
  params: { slug: string };
}) {
  const post = await getPostBySlug(params.slug);
  return <article><h1>{post.title}</h1></article>;
}

Common Mistakes

  • Trying to read searchParams inside a layout.tsx — it's only available to page.tsx.
  • Assuming a page persists state across navigation the way a layout does.
  • Forgetting params and searchParams values are always strings (or string arrays), never numbers or booleans.
  • Adding "use client" to a page purely to use searchParams, when it's already available server-side.

Key Takeaways

  • page.tsx renders the unique content for a specific route and is required to make it reachable.
  • Pages automatically receive params and searchParams as props.
  • Unlike layouts, pages always remount on navigation to a different route.
  • Pages are Server Components by default and can be async for direct data fetching.
  • searchParams is only available on pages, not layouts.

Pro Tip

If you need query-string values inside a layout, pass them down explicitly from the page instead — layouts intentionally don't receive searchParams because a single layout can be shared by many different pages with different query strings.