-
Notifications
You must be signed in to change notification settings - Fork 27.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
merging canary into update-with-styled-jsx-plugins-example.
- Loading branch information
Showing
2 changed files
with
252 additions
and
0 deletions.
There are no files selected for viewing
252 changes: 252 additions & 0 deletions
252
docs/01-app/01-getting-started/02-layouts-and-pages.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
File renamed without changes.