Skip to content

Commit

Permalink
merging canary into update-with-styled-jsx-plugins-example.
Browse files Browse the repository at this point in the history
  • Loading branch information
PapatMayuri committed Nov 26, 2024
2 parents 066d827 + cebecdc commit 6752783
Show file tree
Hide file tree
Showing 2 changed files with 252 additions and 0 deletions.
252 changes: 252 additions & 0 deletions docs/01-app/01-getting-started/02-layouts-and-pages.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
---
title: How to create layouts and pages
nav_title: Layouts and Pages
description: Learn how to create layouts and pages in your Next.js application, and link between them.
related:
title: Learn more about the features mentioned in this page.
links:
- app/api-reference/file-conventions/layout
- app/api-reference/file-conventions/page
- app/api-reference/components/link
---

Next.js uses **file-system based routing**, meaning you can use folders and files to define routes. This page will guide you through how to create layouts and pages, and link between them.

## Creating a page

A **page** is UI that is rendered on a specific route. To create a page, add a [`page` file](/docs/app/api-reference/file-conventions/page) inside the `app` directory and default export a React component. For example, to create an index page (`/`):

<Image
alt="page.js special file"
srcLight="/docs/light/page-special-file.png"
srcDark="/docs/dark/page-special-file.png"
width="1600"
height="282"
/>

```tsx filename="app/page.tsx" switcher
export default function Page() {
return <h1>Hello Next.js!</h1>
}
```

```jsx filename="app/page.js" switcher
export default function Page() {
return <h1>Hello Next.js!</h1>
}
```

## Creating a layout

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

You can define a layout by default exporting a React component from a [`layout` file](/docs/app/api-reference/file-conventions/layout). The component should accept a `children` prop which can be a page or another [layout](#nesting-layouts).

For example, to create a layout that accepts your index page as child, add a `layout` file inside the `app` directory:

<Image
alt="layout.js special file"
srcLight="/docs/light/layout-special-file.png"
srcDark="/docs/dark/layout-special-file.png"
width="1600"
height="363"
/>

```tsx filename="app/layout.tsx" switcher
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
{/* Layout UI */}
{/* Place children where you want to render a page or nested layout */}
<main>{children}</main>
</body>
</html>
)
}
```

```jsx filename="app/layout.js" switcher
export default function DashboardLayout({ children }) {
return (
<html lang="en">
<body>
{/* Layout UI */}
{/* Place children where you want to render a page or nested layout */}
<main>{children}</main>
</body>
</html>
)
}
```

The layout above is called a [root layout](/docs/app/api-reference/file-conventions/layout#root-layouts) because it's defined at the root of the `app` directory.

### Root Layout (Required)

The root layout is defined at the top level and wraps all routes. This layout 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, the `/blog/[slug]` route is composed of three segments:

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

In Next.js:

- **Folders** are used to define the route segments that map to URL segments.
- **Files** (like `page` and `layout`) are used to create UI that is shown for a segment.

To create nested routes, you can nest folders inside each other. For example, to add a route for `/blog`, create a folder called `blog` in the `app` directory. Then, to make `/blog` publicly accessible, add a `page` file:

<Image
alt="File hierarchy showing blog folder and a page.js file"
srcLight="/docs/light/blog-nested-route.png"
srcDark="/docs/dark/blog-nested-route.png"
width="1600"
height="525"
/>

```tsx filename="app/blog/page.tsx" switcher
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 filename="app/blog/[slug]/page.js" switcher
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>
)
}
```

You can continue nesting folders to create nested routes. For example, to create a route for a specific blog post, create a new `[slug]` folder inside `blog` and add a `page` file:

<Image
alt="File hierarchy showing blog folder with a nested slug folder and a page.js file"
srcLight="/docs/light/blog-post-nested-route.png"
srcDark="/docs/dark/blog-post-nested-route.png"
width="1600"
height="687"
/>

```tsx filename="app/blog/[slug]/page.tsx" switcher
function generateStaticParams() {}

export default function Page() {
return <h1>Hello, Blog Post Page!</h1>
}
```

```jsx filename="app/blog/[slug]/page.js" switcher
function generateStaticParams() {}

export default function Page() {
return <h1>Hello, Blog Post Page!</h1>
}
```

> **Good to know**: Wrapping a folder name in square brackets (e.g. `[slug]`) creates a special **dynamic route segment** used to generate multiple pages from data. This is useful for blog posts, product pages, etc. Learn more about [dynamic segments](/docs/app/building-your-application/routing/dynamic-routes).
### Nesting layouts

By default, layouts in the folder hierarchy are also nested, which means they wrap child layouts via their `children` prop. You can nest layouts by adding `layout` inside specific route segments (folders).

For example, to create a layout for the `/blog` route, add a new `layout` file inside the `blog` folder.

<Image
alt="File hierarchy showing root layout wrapping the blog layout"
srcLight="/docs/light/nested-layouts.png"
srcDark="/docs/dark/nested-layouts.png"
width="1600"
height="768"
/>

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

```jsx filename="app/blog/layout.js" switcher
export default function BlogLayout({ children }) {
return <section>{children}</section>
}
```

If you were to combine the two layouts above, the root layout (`app/layout.js`) would wrap the blog layout (`app/blog/layout.js`), which would wrap the blog (`app/blog/page.js`) and blog post page (`app/blog/[slug]/page.js`).

## Linking between pages

You can use the [`<Link>` component](/docs/app/api-reference/components/link) to navigate between routes. `<Link>` is a built-in Next.js component that extends the HTML `<a>` tag to provide prefetching and client-side navigation.

For example, to generate a list of blog posts, import `<Link>` from `next/link` and pass a `href` prop to the component:

```tsx filename="app/ui/post.tsx" highlight={1,6} switcher
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 filename="app/ui/post.js" highlight={1,6} switcher
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>
)
}
```

`<Link>` is the primary and recommended way to navigate between routes in your Next.js application. However, you can also use the [`useRouter` hook](/docs/app/api-reference/functions/use-router) for more advanced navigation.

0 comments on commit 6752783

Please sign in to comment.