Skip to content

Docs IA 2.0: Create Dynamic Segments API reference, add example to getting started. #79439

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: canary
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/01-app/01-getting-started/02-project-structure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ Top-level files are used to configure your application, manage dependencies, run

### Dynamic routes

| | |
| --------------------------------------------------------------------------------------------------------- | -------------------------------- |
| [`[folder]`](/docs/app/building-your-application/routing/dynamic-routes#convention) | Dynamic route segment |
| [`[...folder]`](/docs/app/building-your-application/routing/dynamic-routes#catch-all-segments) | Catch-all route segment |
| [`[[...folder]]`](/docs/app/building-your-application/routing/dynamic-routes#optional-catch-all-segments) | Optional catch-all route segment |
| | |
| ------------------------------------------------------------------------------------------------------ | -------------------------------- |
| [`[folder]`](/docs/app/api-reference/file-conventions/dynamic-routes#convention) | Dynamic route segment |
| [`[...folder]`](/docs/app/api-reference/file-conventions/dynamic-routes#catch-all-segments) | Catch-all route segment |
| [`[[...folder]]`](/docs/app/api-reference/file-conventions/dynamic-routes#optional-catch-all-segments) | Optional catch-all route segment |

### Route Groups and private folders

Expand Down
43 changes: 42 additions & 1 deletion docs/01-app/01-getting-started/03-layouts-and-pages.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ related:
- app/api-reference/file-conventions/layout
- app/api-reference/file-conventions/page
- app/api-reference/components/link
- app/api-reference/file-conventions/dynamic-routes
---

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.
Expand Down Expand Up @@ -172,7 +173,7 @@ export default function Page() {
}
```

Wrapping a folder name in square brackets (e.g. `[slug]`) creates a [dynamic route segment](/docs/app/building-your-application/routing/dynamic-routes) which is used to generate multiple pages from data. e.g. blog posts, product pages, etc.
Wrapping a folder name in square brackets (e.g. `[slug]`) creates a [dynamic route segment](/docs/app/api-reference/file-conventions/dynamic-routes) which is used to generate multiple pages from data. e.g. blog posts, product pages, etc.

## Nesting layouts

Expand Down Expand Up @@ -206,6 +207,46 @@ export default function BlogLayout({ children }) {

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`).

## Creating a dynamic segment

[Dynamic segments](/docs/app/api-reference/file-conventions/dynamic-routes) allow you to create routes that are generated from data. For example, instead of manually creating a route for each individual blog post, you can create a dynamic segment to generate the routes based on blog post data.

To create a dynamic segment, wrap the segment (folder) name in square brackets: `[segmentName]`. For example, in the `app/blog/[slug]/page.tsx` route, the `[slug]` is the dynamic segment.

```tsx filename="app/blog/[slug]/page.tsx" switcher
export default 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 filename="app/blog/[slug]/page.js" switcher
export default function BlogPostPage({ params }) {
const { slug } = await params
const post = await getPost(slug)

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

Learn more about [Dynamic Segments](/docs/app/api-reference/file-conventions/dynamic-routes).

## 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](/docs/app/building-your-application/routing/linking-and-navigating#2-prefetching) and [client-side navigation](/docs/app/building-your-application/routing/linking-and-navigating#5-soft-navigation).
Expand Down
2 changes: 1 addition & 1 deletion docs/01-app/02-guides/migrating/from-create-react-app.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ If you’re using Tailwind CSS, see our [installation docs](/docs/app/guides/tai

Create React App uses `src/index.tsx` (or `index.js`) as the entry point. In Next.js (App Router), each folder inside the `app` directory corresponds to a route, and each folder should have a `page.tsx`.

Since we want to keep the app as an SPA for now and intercept **all** routes, we’ll use an [optional catch-all route](/docs/app/building-your-application/routing/dynamic-routes#optional-catch-all-segments).
Since we want to keep the app as an SPA for now and intercept **all** routes, we’ll use an [optional catch-all route](/docs/app/api-reference/file-conventions/dynamic-routes#optional-catch-all-segments).

1. **Create a `[[...slug]]` directory inside `app`.**

Expand Down
2 changes: 1 addition & 1 deletion docs/01-app/02-guides/migrating/from-vite.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ entrypoint of your application.

Since in this guide we're aiming first to set up our Next.js as an SPA (Single Page Application), you need your page entrypoint to catch all possible routes of your application. For that, create a new `[[...slug]]` directory in your `app` directory.

This directory is what is called an [optional catch-all route segment](/docs/app/building-your-application/routing/dynamic-routes#optional-catch-all-segments). Next.js uses a file-system based router where folders are used to define routes. This special directory will make sure that all routes of your application will be directed to its containing `page.tsx` file.
This directory is what is called an [optional catch-all route segment](/docs/app/api-reference/file-conventions/dynamic-routes#optional-catch-all-segments). Next.js uses a file-system based router where folders are used to define routes. This special directory will make sure that all routes of your application will be directed to its containing `page.tsx` file.

2. **Create a new `page.tsx` file inside the `app/[[...slug]]` directory with the following content:**

Expand Down
8 changes: 4 additions & 4 deletions docs/01-app/02-guides/static-exports.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ After running `next build`, Next.js will create an `out` folder with the HTML/CS

<PagesOnly>

You can utilize [`getStaticProps`](/docs/pages/building-your-application/data-fetching/get-static-props) and [`getStaticPaths`](/docs/pages/building-your-application/data-fetching/get-static-paths) to generate an HTML file for each page in your `pages` directory (or more for [dynamic routes](/docs/app/building-your-application/routing/dynamic-routes)).
You can utilize [`getStaticProps`](/docs/pages/building-your-application/data-fetching/get-static-props) and [`getStaticPaths`](/docs/pages/building-your-application/data-fetching/get-static-paths) to generate an HTML file for each page in your `pages` directory (or more for [dynamic routes](/docs/app/api-reference/file-conventions/dynamic-routes)).

</PagesOnly>

Expand Down Expand Up @@ -154,7 +154,7 @@ export default function Page() {

The majority of core Next.js features needed to build a static site are supported, including:

- [Dynamic Routes when using `getStaticPaths`](/docs/app/building-your-application/routing/dynamic-routes)
- [Dynamic Routes when using `getStaticPaths`](/docs/app/api-reference/file-conventions/dynamic-routes)
- Prefetching with `next/link`
- Preloading JavaScript
- [Dynamic Imports](/docs/pages/guides/lazy-loading)
Expand Down Expand Up @@ -277,8 +277,8 @@ Features that require a Node.js server, or dynamic logic that cannot be computed

<AppOnly>

- [Dynamic Routes](/docs/app/building-your-application/routing/dynamic-routes) with `dynamicParams: true`
- [Dynamic Routes](/docs/app/building-your-application/routing/dynamic-routes) without `generateStaticParams()`
- [Dynamic Routes](/docs/app/api-reference/file-conventions/dynamic-routes) with `dynamicParams: true`
- [Dynamic Routes](/docs/app/api-reference/file-conventions/dynamic-routes) without `generateStaticParams()`
- [Route Handlers](/docs/app/building-your-application/routing/route-handlers) that rely on Request
- [Cookies](/docs/app/api-reference/functions/cookies)
- [Rewrites](/docs/app/api-reference/config/next-config-js/rewrites)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ export async function GET(request) {

### Dynamic Route Segments

Route Handlers can use [Dynamic Segments](/docs/app/building-your-application/routing/dynamic-routes) to create request handlers from dynamic data.
Route Handlers can use [Dynamic Segments](/docs/app/api-reference/file-conventions/dynamic-routes) to create request handlers from dynamic data.

```ts filename="app/items/[slug]/route.ts" switcher
export async function GET(
Expand Down
4 changes: 2 additions & 2 deletions docs/01-app/04-deep-dive/caching.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ See the [Route Segment Config](/docs/app/api-reference/file-conventions/route-se

### `generateStaticParams`

For [dynamic segments](/docs/app/building-your-application/routing/dynamic-routes) (e.g. `app/blog/[slug]/page.js`), paths provided by `generateStaticParams` are cached in the Full Route Cache at build time. At request time, Next.js will also cache paths that weren't known at build time the first time they're visited.
For [dynamic segments](/docs/app/api-reference/file-conventions/dynamic-routes) (e.g. `app/blog/[slug]/page.js`), paths provided by `generateStaticParams` are cached in the Full Route Cache at build time. At request time, Next.js will also cache paths that weren't known at build time the first time they're visited.

To statically render all paths at build time, supply the full list of paths to `generateStaticParams`:

Expand Down Expand Up @@ -563,7 +563,7 @@ export async function generateStaticParams() {
export const dynamic = 'force-static'
```

To disable caching at request time, add the `export const dynamicParams = false` option in a route segment. When this config option is used, only paths provided by `generateStaticParams` will be served, and other routes will 404 or match (in the case of [catch-all routes](/docs/app/building-your-application/routing/dynamic-routes#catch-all-segments)).
To disable caching at request time, add the `export const dynamicParams = false` option in a route segment. When this config option is used, only paths provided by `generateStaticParams` will be served, and other routes will 404 or match (in the case of [catch-all routes](/docs/app/api-reference/file-conventions/dynamic-routes#catch-all-segments)).

### React `cache` function

Expand Down
8 changes: 4 additions & 4 deletions docs/01-app/05-api-reference/02-components/link.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ The following examples demonstrate how to use the `<Link>` component in differen

### Linking to dynamic segments

When linking to [dynamic segments](/docs/app/building-your-application/routing/dynamic-routes), you can use [template literals and interpolation](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Template_literals) to generate a list of links. For example, to generate a list of blog posts:
When linking to [dynamic segments](/docs/app/api-reference/file-conventions/dynamic-routes), you can use [template literals and interpolation](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Template_literals) to generate a list of links. For example, to generate a list of blog posts:

```tsx filename="app/blog/post-list.tsx" switcher
import Link from 'next/link'
Expand Down Expand Up @@ -629,7 +629,7 @@ If you'd like to scroll to a specific `id` on navigation, you can append your UR

### Linking to dynamic route segments

For [dynamic route segments](/docs/app/building-your-application/routing/dynamic-routes), it can be handy to use template literals to create the link's path.
For [dynamic route segments](/docs/app/api-reference/file-conventions/dynamic-routes), it can be handy to use template literals to create the link's path.

<PagesOnly>

Expand Down Expand Up @@ -973,7 +973,7 @@ export default Home
The above example has a link to:

- A predefined route: `/about?name=test`
- A [dynamic route](/docs/app/building-your-application/routing/dynamic-routes): `/blog/my-post`
- A [dynamic route](/docs/app/api-reference/file-conventions/dynamic-routes): `/blog/my-post`

You can use every property as defined in the [Node.js URL module documentation](https://nodejs.org/api/url.html#url_url_strings_and_url_objects).

Expand Down Expand Up @@ -1230,7 +1230,7 @@ export default function Home() {

<PagesOnly>

> **Good to know**: If you're using [Dynamic Routes](/docs/app/building-your-application/routing/dynamic-routes), you'll need to adapt your `as` and `href` props. For example, if you have a Dynamic Route like `/dashboard/authed/[user]` that you want to present differently via middleware, you would write: `<Link href={{ pathname: '/dashboard/authed/[user]', query: { user: username } }} as="/dashboard/[user]">Profile</Link>`.
> **Good to know**: If you're using [Dynamic Routes](/docs/app/api-reference/file-conventions/dynamic-routes), you'll need to adapt your `as` and `href` props. For example, if you have a Dynamic Route like `/dashboard/authed/[user]` that you want to present differently via middleware, you would write: `<Link href={{ pathname: '/dashboard/authed/[user]', query: { user: username } }} as="/dashboard/[user]">Profile</Link>`.

</PagesOnly>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ The default export function receives the following props:

#### `params` (optional)

An object containing the [dynamic route parameters](/docs/app/building-your-application/routing/dynamic-routes) object from the root segment down to the segment `icon` or `apple-icon` is colocated in.
An object containing the [dynamic route parameters](/docs/app/api-reference/file-conventions/dynamic-routes) object from the root segment down to the segment `icon` or `apple-icon` is colocated in.

```tsx filename="app/shop/[slug]/icon.tsx" switcher
export default function Icon({ params }: { params: { slug: string } }) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ The default export function receives the following props:

#### `params` (optional)

An object containing the [dynamic route parameters](/docs/app/building-your-application/routing/dynamic-routes) object from the root segment down to the segment `opengraph-image` or `twitter-image` is colocated in.
An object containing the [dynamic route parameters](/docs/app/api-reference/file-conventions/dynamic-routes) object from the root segment down to the segment `opengraph-image` or `twitter-image` is colocated in.

```tsx filename="app/shop/[slug]/opengraph-image.tsx" switcher
export default function Image({ params }: { params: { slug: string } }) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Additionally, since `children` is an implicit slot, you also need to create a `d

### `params` (optional)

A promise that resolves to an object containing the [dynamic route parameters](/docs/app/building-your-application/routing/dynamic-routes) from the root segment down to the slot's subpages. For example:
A promise that resolves to an object containing the [dynamic route parameters](/docs/app/api-reference/file-conventions/dynamic-routes) from the root segment down to the slot's subpages. For example:

```tsx filename="app/[artist]/@sidebar/default.js" switcher
export default async function Default({
Expand Down
Loading
Loading