Skip to content

Commit b168933

Browse files
committed
docs: next-root-params
1 parent f618d0b commit b168933

File tree

1 file changed

+208
-0
lines changed

1 file changed

+208
-0
lines changed
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
---
2+
title: next/root-params
3+
description: API Reference for the next/root-params module that provides access to root-level route parameters.
4+
version: canary
5+
---
6+
7+
The `next/root-params` module provides individual getter functions for accessing root-level route parameters in **Server Components**. This experimental feature enables type-safe access to parameters defined in root layout segments.
8+
9+
## Configuration
10+
11+
To use `next/root-params`, you must enable the experimental flag in your `next.config.js`:
12+
13+
```js filename="next.config.js"
14+
/** @type {import('next').NextConfig} */
15+
const nextConfig = {
16+
experimental: {
17+
rootParams: true,
18+
},
19+
}
20+
21+
module.exports = nextConfig
22+
```
23+
24+
## Usage
25+
26+
The module automatically generates individual getter functions for each root parameter found in your app directory structure. Root parameters are dynamic segments that appear in the path leading up to the first `layout.tsx` file.
27+
28+
```tsx filename="app/[lang]/[locale]/page.tsx"
29+
import { lang, locale } from 'next/root-params'
30+
31+
export default async function Page() {
32+
return (
33+
<div>
34+
<h1>Language: {await lang()}</h1>
35+
<p>Locale: {await locale()}</p>
36+
</div>
37+
)
38+
}
39+
```
40+
41+
```tsx filename="app/[lang]/[locale]/layout.tsx"
42+
import { lang, locale } from 'next/root-params'
43+
44+
export default async function Layout({ children }) {
45+
return (
46+
<html lang={`${await lang()}-${await locale()}`}>
47+
<body>{children}</body>
48+
</html>
49+
)
50+
}
51+
52+
export async function generateStaticParams() {
53+
return [
54+
{ lang: 'en', locale: 'us' },
55+
{ lang: 'fr', locale: 'ca' },
56+
]
57+
}
58+
```
59+
60+
## Root Parameters vs Dynamic Parameters
61+
62+
Root parameters are different from regular dynamic parameters. They are only the parameters that exist in the path segments up to the first layout file:
63+
64+
File structure:
65+
66+
- `app/[lang]/[locale]/layout.tsx` - Root layout
67+
- `app/[lang]/[locale]/posts/[slug]/page.tsx`
68+
69+
```tsx
70+
import { lang, locale } from 'next/root-params' // Available
71+
// import { slug } from 'next/root-params' // Not available - 'slug' is not a root param
72+
73+
export default async function PostPage({
74+
params,
75+
}: {
76+
params: { slug: string }
77+
}) {
78+
const { slug } = await params // Access non-root params this way
79+
80+
return (
81+
<div>
82+
<h1>Language: {await lang()}</h1>
83+
<h2>Locale: {await locale()}</h2>
84+
<h3>Post: {slug}</h3>
85+
</div>
86+
)
87+
}
88+
```
89+
90+
## Multiple Root Layouts
91+
92+
Applications can have multiple root layouts with different parameter structures:
93+
94+
File structure:
95+
96+
- `app/dashboard/[id]/layout.tsx` - Root layout with 'id' param
97+
- `app/marketing/layout.tsx` - Root layout with no params
98+
99+
```tsx
100+
// In dashboard pages:
101+
import { id } from 'next/root-params'
102+
103+
export default async function DashboardPage() {
104+
const dashboardId = await id() // Type: string | undefined
105+
return <div>Dashboard ID: {dashboardId}</div>
106+
}
107+
108+
// In marketing pages:
109+
import { id } from 'next/root-params'
110+
111+
export default async function MarketingPage() {
112+
const dashboardId = await id() // Type: string | undefined, returns undefined
113+
return <div>Marketing Page</div>
114+
}
115+
```
116+
117+
When you have multiple root layouts with different parameters, the getter functions are typed to account for all possible routes. Since `id` doesn't exist in the marketing layout, `await id()` has the type `string | undefined` to reflect that it may return `undefined` when accessed from routes without that parameter.
118+
119+
## Catch-all and Optional Catch-all Routes
120+
121+
Root parameters work with catch-all and optional catch-all routes:
122+
123+
```tsx filename="app/docs/[...path]/layout.tsx"
124+
import { path } from 'next/root-params'
125+
126+
export default async function DocsLayout({ children }) {
127+
const pathSegments = await path() // string[] | undefined
128+
return (
129+
<div>
130+
<nav>Path: {pathSegments?.join(' / ')}</nav>
131+
{children}
132+
</div>
133+
)
134+
}
135+
```
136+
137+
```tsx filename="app/optional/[[...segments]]/page.tsx"
138+
import { segments } from 'next/root-params'
139+
140+
export default async function OptionalPage() {
141+
const pathSegments = await segments() // string[] | undefined
142+
return (
143+
<div>
144+
{pathSegments ? (
145+
<p>Segments: {pathSegments.join(', ')}</p>
146+
) : (
147+
<p>No segments</p>
148+
)}
149+
</div>
150+
)
151+
}
152+
```
153+
154+
## Return Values
155+
156+
Each root parameter getter returns a `Promise` that resolves to:
157+
158+
- `string` for regular dynamic segments like `[id]`
159+
- `string[]` for catch-all segments like `[...path]`
160+
- `string[] | undefined` for optional catch-all segments like `[[...path]]`
161+
- `undefined` if the parameter doesn't exist in the current route's root layout
162+
163+
## Restrictions
164+
165+
### Server Components Only
166+
167+
Root parameter getters can only be used in **Server Components**:
168+
169+
```tsx
170+
// This will cause a build error
171+
'use client'
172+
173+
import { lang } from 'next/root-params' // Error: Cannot import in Client Component
174+
175+
export default function ClientComponent() {
176+
// ...
177+
}
178+
```
179+
180+
### Not Available in Server Actions
181+
182+
```tsx
183+
import { lang } from 'next/root-params'
184+
185+
// This will cause a runtime error
186+
async function serverAction() {
187+
'use server'
188+
const language = await lang() // Error: Not supported in Server Actions
189+
}
190+
```
191+
192+
### Not Available in Route Handlers
193+
194+
```tsx filename="app/[lang]/api/route.ts"
195+
import { lang } from 'next/root-params'
196+
197+
// This will cause a runtime error (support planned for future)
198+
export async function GET() {
199+
const language = await lang() // Error: Not supported in Route Handlers yet
200+
return Response.json({ lang: language })
201+
}
202+
```
203+
204+
## Version History
205+
206+
| Version | Changes |
207+
| --------- | ------------------------------------------------------ |
208+
| `v15.1.0` | `next/root-params` introduced as experimental feature. |

0 commit comments

Comments
 (0)