Skip to content

Commit 0d49faf

Browse files
authored
docs: next/root-params references on i18n guide (vercel#94629)
x-ref to next/root-params from the i18n guide
1 parent 073bb78 commit 0d49faf

1 file changed

Lines changed: 73 additions & 0 deletions

File tree

docs/01-app/02-guides/internationalization.mdx

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
---
22
title: Internationalization
33
description: Add support for multiple languages with internationalized routing and localized content.
4+
related:
5+
description: Related API references and conventions.
6+
links:
7+
- app/api-reference/functions/next-root-params
48
---
59

610
Next.js enables you to configure the routing and rendering of content to support multiple languages. Making your site adaptive to different locales includes translated content (localization) and internationalized routes.
@@ -178,6 +182,75 @@ export default async function Page({ params }) {
178182

179183
Because all layouts and pages in the `app/` directory default to [Server Components](/docs/app/getting-started/server-and-client-components), we do not need to worry about the size of the translation files affecting our client-side JavaScript bundle size. This code will **only run on the server**, and only the resulting HTML will be sent to the browser.
180184

185+
## Sharing the locale across your app
186+
187+
The locale is often needed beyond the page that receives it, such as in shared data-fetching utilities or deeply nested components. Instead of prop drilling `lang` through each layer, we can read it directly with [`next/root-params`](/docs/app/api-reference/functions/next-root-params).
188+
189+
`next/root-params` exports a getter for each dynamic segment above the root layout. Since every route is nested under `app/[lang]`, `lang` is a root parameter, and any Server Component or server-side utility can call its getter. We can move the locale lookup into `getDictionary`, so callers no longer pass `lang`:
190+
191+
```ts filename="app/[lang]/dictionaries.ts" highlight={1,2,15,16,17} switcher
192+
import { lang } from 'next/root-params'
193+
import { notFound } from 'next/navigation'
194+
195+
const dictionaries = {
196+
en: () => import('./dictionaries/en.json').then((module) => module.default),
197+
nl: () => import('./dictionaries/nl.json').then((module) => module.default),
198+
}
199+
200+
export type Locale = keyof typeof dictionaries
201+
202+
export const hasLocale = (locale: string): locale is Locale =>
203+
locale in dictionaries
204+
205+
export const getDictionary = async () => {
206+
const locale = await lang()
207+
if (!hasLocale(locale)) notFound()
208+
return dictionaries[locale]()
209+
}
210+
```
211+
212+
```js filename="app/[lang]/dictionaries.js" highlight={1,2,12,13,14} switcher
213+
import { lang } from 'next/root-params'
214+
import { notFound } from 'next/navigation'
215+
216+
const dictionaries = {
217+
en: () => import('./dictionaries/en.json').then((module) => module.default),
218+
nl: () => import('./dictionaries/nl.json').then((module) => module.default),
219+
}
220+
221+
export const hasLocale = (locale) => locale in dictionaries
222+
223+
export const getDictionary = async () => {
224+
const locale = await lang()
225+
if (!hasLocale(locale)) notFound()
226+
return dictionaries[locale]()
227+
}
228+
```
229+
230+
> **Good to know:** Files that import from `next/root-params` do not need `import 'server-only'`. The import already fails at build time if used in a Client Component.
231+
232+
Pages and components then call `getDictionary()` with no arguments, since the locale is resolved internally:
233+
234+
```tsx filename="app/[lang]/page.tsx" highlight={4} switcher
235+
import { getDictionary } from './dictionaries'
236+
237+
export default async function Page() {
238+
const dict = await getDictionary()
239+
return <button>{dict.products.cart}</button> // Add to Cart
240+
}
241+
```
242+
243+
```jsx filename="app/[lang]/page.js" highlight={4} switcher
244+
import { getDictionary } from './dictionaries'
245+
246+
export default async function Page() {
247+
const dict = await getDictionary()
248+
return <button>{dict.products.cart}</button> // Add to Cart
249+
}
250+
```
251+
252+
> **Good to know:** Root parameter getters run in Server Components and server-side utilities, but not in Client Components, Server Actions, or Route Handlers. See [`next/root-params`](/docs/app/api-reference/functions/next-root-params) for the full API and its behavior with caching.
253+
181254
## Static Rendering
182255

183256
To generate static routes for a given set of locales, we can use `generateStaticParams` with any page or layout. This can be global, for example, in the root layout:

0 commit comments

Comments
 (0)