Skip to content
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

Add initial i18n documentation #18067

Merged
merged 9 commits into from Oct 23, 2020
Merged
135 changes: 135 additions & 0 deletions docs/advanced-features/i18n-routing.md
@@ -0,0 +1,135 @@
# Internationalized Routing

<details>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/i18n-routing">i18n routing</a></li>
ijjk marked this conversation as resolved.
Show resolved Hide resolved
</ul>
</details>

Next.js has built-in support for internationalized ([i18n](https://en.wikipedia.org/wiki/Internationalization_and_localization#Naming)) routing since `v9.5.7`. You can provide a list of locales, the default locale, and domain-specific locales and Next.js will automatically handle the routing.

The i18n routing support is currently meant to complement existing i18n library solutions like react-intl, react-i18next, lingui, rosetta, and others by streamlining the routes and locale parsing.

## Getting started

To get started, add the `i18n` config to your `next.config.js` file.

```js
module.exports = {
i18n: {
// These are all the locales you want to support in
// your application
locales: ['en-US', 'fr', 'nl-NL'],
// This is the default locale you want to be used when visiting
// a non-local prefixed path e.g. `/hello`
defaultLocale: 'en-US',
// These are a list of locale domains and the default locale they
// should handle (these are not required)
domains: [
{
domain: 'example.com',
defaultLocale: 'en-US',
},
{
domain: 'example.nl',
defaultLocale: 'nl-NL',
},
{
domain: 'example.fr',
defaultLocale: 'fr',
},
],
},
}
```

## How are the routes handled

When a user visits `/`, Next.js will try to automatically detect which locale the user prefers with the [`Accept-Language`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) header and the current domain.

If a locale other than the default locale is detected, the user will be redirected to either:

A) The domain with that locale specified as the default.
B) The locale prefixed path if no domain matched.

For example, if a user with the `Accept-Language` header `fr;q=0.9` visits `example.com`, they will be redirected to `example.fr` since that domain handles the `fr` locale by default.

If we did not have the `example.fr` domain configured, then the user would instead be redirected to `/fr`.

## Accessing the locale information

On the `next/router` instance available via the [`useRouter()`](https://nextjs.org/docs/api-reference/next/router#userouter) hook. It has the following fields:

- `locale` contains the active locale.
- `locales` contains all supported locales.
- `defaultLocale` contains the current default locale.

When [prerendering](/docs/basic-features/pages#static-generation-recommended) pages with `getStaticProps`, the locale information is provided in [the context](https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation) provided to the function.

When leveraging `getStaticPaths`, the supported locales are provided in the context provided to the function under `locales`.

## Transition between locales

You can use `next/link` or `next/router` to transition between locales.

For `next/link`, a `locale` prop can be provided to transition to a different locale from the currently active one. If no `locale` prop is provided, the currently active `locale` is used during client-transitions. For example:

```jsx
import Link from 'next/link'

export default function IndexPage(props) {
return (
<Link href="/another" locale="fr">
<a>To /fr/another</a>
</Link>
)
}
```

When using the `next/router` methods directly, you can specify the `locale` that should be used via the transition options. For example:

```jsx
import { useRouter } from 'next/router'

export default function IndexPage(props) {
const router = useRouter()

return (
<div
onClick={() => {
router.push('/another', '/another', { locale: 'fr' })
}}
>
to /fr/another
</div>
)
}
```

## How does this work with static generation?

### Automatically Statically Optimized Pages

For pages that are automatically statically optimized, a version of the page will be generated for each locale. This ensures the `lang` HTML attribute and `router.locale` value have the correct initial values for each locale.

### Non-dynamic getStaticProps Pages

For non-dynamic `getStaticProps` pages, a version is generated for each locale like above. `getStaticProps` is also called with each `locale` that is being rendered. If you would like to opt-out of a certain locale from being pre-rendered, you can return `notFound: true` from `getStaticProps` and this variant of the page will not be generated.

### Dynamic getStaticProps Pages

For dynamic `getStaticProps` pages, any locale variants of the page that is desired to be prerendered needs to be returned from [`getStaticPaths`](/docs/basic-features/data-fetching#getstaticpaths-static-generation). Along with the `params` object that can be returned for the `paths`, you can also return a `locale` field specifying which locale you want to render. For example:

```js
// pages/blog/[slug].js
export const getStaticPaths = ({ locales }) => {
return {
paths: [
{ params: { slug: 'post-1' }, locale: 'en-US' },
{ params: { slug: 'post-1' }, locale: 'fr' },
],
fallback: true,
}
}
```
7 changes: 6 additions & 1 deletion docs/api-reference/next/router.md
Expand Up @@ -43,7 +43,12 @@ The following is the definition of the `router` object returned by both [`useRou

- `pathname`: `String` - Current route. That is the path of the page in `/pages`
- `query`: `Object` - The query string parsed to an object. It will be an empty object during prerendering if the page doesn't have [data fetching requirements](/docs/basic-features/data-fetching.md). Defaults to `{}`
- `asPath`: `String` - Actual path (including the query) shown in the browser
- `asPath`: `String` - Actual path (including the query) shown in the browser.
- `isFallback`: `boolean` - Whether the current page is in [fallback mode](/docs/basic-features/data-fetching#fallback-pages).
- `basePath`: `String` - The active [basePath](/docs/api-reference/next.config.js/basepath) (if enabled).
- `locale`: `String` - The active locale (if enabled).
- `locales`: `String[]` - All supported locales (if enabled).
- `defaultLocale`: `String` - The current default locale (if enabled).

Additionally, the following methods are also included inside `router`:

Expand Down
3 changes: 3 additions & 0 deletions docs/basic-features/data-fetching.md
Expand Up @@ -54,11 +54,14 @@ The `context` parameter is an object containing the following keys:
- `params` contains the route parameters for pages using dynamic routes. For example, if the page name is `[id].js` , then `params` will look like `{ id: ... }`. To learn more, take a look at the [Dynamic Routing documentation](/docs/routing/dynamic-routes.md). You should use this together with `getStaticPaths`, which we’ll explain later.
- `preview` is `true` if the page is in the preview mode and `undefined` otherwise. See the [Preview Mode documentation](/docs/advanced-features/preview-mode.md).
- `previewData` contains the preview data set by `setPreviewData`. See the [Preview Mode documentation](/docs/advanced-features/preview-mode.md).
- `locale` contains the active locale (if enabled).
- `locales` contains all supported locales (if enabled).

`getStaticProps` should return an object with:

- `props` - A **required** object with the props that will be received by the page component. It should be a [serializable object](https://en.wikipedia.org/wiki/Serialization)
- `revalidate` - An **optional** amount in seconds after which a page re-generation can occur. More on [Incremental Static Regeneration](#incremental-static-regeneration)
- `notFound` - An optional boolean value to allow the page to return a 404 status and page. More on [Incremental Static Regeneration](#incremental-static-regeneration)

> **Note**: You can import modules in top-level scope for use in `getStaticProps`.
> Imports used in `getStaticProps` will [not be bundled for the client-side](#write-server-side-code-directly).
Expand Down