> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/vercel/next.js/llms.txt
> Use this file to discover all available pages before exploring further.

# Layouts and pages

> Create your first pages and shared layouts, link between them, and use dynamic segments to generate routes from data.

Next.js uses **file-system based routing** — folders and files inside the `app` directory define your routes. This guide walks through how to create pages, layouts, nested routes, dynamic segments, and links.

## Creating a page

A **page** is UI rendered on a specific route. Create a page by adding a `page` file inside the `app` directory and default-exporting a React component.

<CodeGroup>
  ```tsx app/page.tsx theme={null}
  export default function Page() {
    return <h1>Hello Next.js!</h1>
  }
  ```

  ```jsx app/page.js theme={null}
  export default function Page() {
    return <h1>Hello Next.js!</h1>
  }
  ```
</CodeGroup>

## Creating a layout

A **layout** is UI shared between multiple pages. On navigation, layouts preserve state, remain interactive, and do not re-render.

Create a layout by default-exporting a React component from a `layout` file. The component must accept a `children` prop, which will receive a page or another nested layout.

<CodeGroup>
  ```tsx app/layout.tsx theme={null}
  export default function DashboardLayout({
    children,
  }: {
    children: React.ReactNode
  }) {
    return (
      <html lang="en">
        <body>
          {/* Layout UI */}
          <main>{children}</main>
        </body>
      </html>
    )
  }
  ```

  ```jsx app/layout.js theme={null}
  export default function DashboardLayout({ children }) {
    return (
      <html lang="en">
        <body>
          {/* Layout UI */}
          <main>{children}</main>
        </body>
      </html>
    )
  }
  ```
</CodeGroup>

The layout at `app/layout.tsx` is the **root layout**. It is required and must contain `<html>` and `<body>` tags.

## Creating a nested route

A nested route is a route composed of multiple URL segments. For example, `/blog/[slug]` is composed of three segments:

* `/` (Root Segment)
* `blog` (Segment)
* `[slug]` (Leaf Segment)

In Next.js:

* **Folders** define the route segments that map to URL segments.
* **Files** like `page` and `layout` define the UI shown for a segment.

To add a route for `/blog`, create a `blog` folder inside `app`, then add a `page.tsx` file inside it:

<CodeGroup>
  ```tsx app/blog/page.tsx theme={null}
  import { getPosts } from '@/lib/posts'
  import { Post } from '@/ui/post'

  export default async function Page() {
    const posts = await getPosts()

    return (
      <ul>
        {posts.map((post) => (
          <Post key={post.id} post={post} />
        ))}
      </ul>
    )
  }
  ```

  ```jsx app/blog/page.js theme={null}
  import { getPosts } from '@/lib/posts'
  import { Post } from '@/ui/post'

  export default async function Page() {
    const posts = await getPosts()

    return (
      <ul>
        {posts.map((post) => (
          <Post key={post.id} post={post} />
        ))}
      </ul>
    )
  }
  ```
</CodeGroup>

## Nesting layouts

Layouts in the folder hierarchy are nested by default — they wrap child layouts via their `children` prop.

To create a layout for `/blog`, add a `layout` file inside the `blog` folder:

<CodeGroup>
  ```tsx app/blog/layout.tsx theme={null}
  export default function BlogLayout({
    children,
  }: {
    children: React.ReactNode
  }) {
    return <section>{children}</section>
  }
  ```

  ```jsx app/blog/layout.js theme={null}
  export default function BlogLayout({ children }) {
    return <section>{children}</section>
  }
  ```
</CodeGroup>

With both layouts in place, the root layout (`app/layout.js`) wraps the blog layout (`app/blog/layout.js`), which in turn wraps the blog index page (`app/blog/page.js`) and every blog post page (`app/blog/[slug]/page.js`).

## Creating a dynamic segment

[Dynamic segments](/app/core-concepts/routing) let you generate routes from data. Wrap a folder name in square brackets to create a dynamic segment: `[segmentName]`.

For example, `app/blog/[slug]/page.tsx` creates a dynamic route for each blog post where `[slug]` is the dynamic parameter:

<CodeGroup>
  ```tsx app/blog/[slug]/page.tsx theme={null}
  export default async function BlogPostPage({
    params,
  }: {
    params: Promise<{ slug: string }>
  }) {
    const { slug } = await params
    const post = await getPost(slug)

    return (
      <div>
        <h1>{post.title}</h1>
        <p>{post.content}</p>
      </div>
    )
  }
  ```

  ```jsx app/blog/[slug]/page.js theme={null}
  export default async function BlogPostPage({ params }) {
    const { slug } = await params
    const post = await getPost(slug)

    return (
      <div>
        <h1>{post.title}</h1>
        <p>{post.content}</p>
      </div>
    )
  }
  ```
</CodeGroup>

<Tip>
  To pre-generate static pages for a dynamic segment at build time, export `generateStaticParams` from the page. This avoids falling back to dynamic rendering at request time.
</Tip>

## Rendering with search params

In a Server Component page, you can read search parameters from the URL using the `searchParams` prop:

<CodeGroup>
  ```tsx app/page.tsx theme={null}
  export default async function Page({
    searchParams,
  }: {
    searchParams: Promise<{ [key: string]: string | string[] | undefined }>
  }) {
    const filters = (await searchParams).filters
  }
  ```

  ```jsx app/page.jsx theme={null}
  export default async function Page({ searchParams }) {
    const filters = (await searchParams).filters
  }
  ```
</CodeGroup>

<Note>
  Using `searchParams` opts your page into **dynamic rendering** because it requires an incoming request to read the search parameters. Client Components can read search params using the `useSearchParams` hook instead.
</Note>

### When to use each approach

| Use case                                                    | Approach                                      |
| ----------------------------------------------------------- | --------------------------------------------- |
| Load data based on search params (pagination, DB filtering) | `searchParams` prop in Server Component       |
| Filter a list already loaded via props (client-only)        | `useSearchParams` hook in Client Component    |
| Read params in event handlers without re-renders            | `new URLSearchParams(window.location.search)` |

## Linking between pages

Use the `<Link>` component to navigate between routes. `<Link>` is a built-in Next.js component that extends the HTML `<a>` tag to provide [prefetching](/app/getting-started/linking-and-navigating#prefetching) and client-side navigation.

<CodeGroup>
  ```tsx app/ui/post.tsx theme={null}
  import Link from 'next/link'

  export default async function Post({ post }) {
    const posts = await getPosts()

    return (
      <ul>
        {posts.map((post) => (
          <li key={post.slug}>
            <Link href={`/blog/${post.slug}`}>{post.title}</Link>
          </li>
        ))}
      </ul>
    )
  }
  ```

  ```jsx app/ui/post.js theme={null}
  import Link from 'next/link'

  export default async function Post({ post }) {
    const posts = await getPosts()

    return (
      <ul>
        {posts.map((post) => (
          <li key={post.slug}>
            <Link href={`/blog/${post.slug}`}>{post.title}</Link>
          </li>
        ))}
      </ul>
    )
  }
  ```
</CodeGroup>

`<Link>` is the primary way to navigate between routes. You can also use the `useRouter` hook for more advanced navigation patterns.

## Route Props Helpers

Next.js exposes globally-available utility types that infer `params` and named slots from your route structure — no imports required. They are generated when running `next dev`, `next build`, or `next typegen`.

* **`PageProps`** — props for `page` components, including `params` and `searchParams`.
* **`LayoutProps`** — props for `layout` components, including `children` and any named slots.

```tsx app/blog/[slug]/page.tsx theme={null}
export default async function Page(props: PageProps<'/blog/[slug]'>) {
  const { slug } = await props.params
  return <h1>Blog post: {slug}</h1>
}
```

```tsx app/dashboard/layout.tsx theme={null}
export default function Layout(props: LayoutProps<'/dashboard'>) {
  return (
    <section>
      {props.children}
      {/* If you have app/dashboard/@analytics, it appears as a typed slot */}
      {/* {props.analytics} */}
    </section>
  )
}
```

<Note>
  Static routes resolve `params` to `{}`. Types are generated during `next dev`, `next build`, or `next typegen`.
</Note>
