diff --git a/src/content/docs/en/guides/internationalization.mdx b/src/content/docs/en/guides/internationalization.mdx index 0eba79a5de618..3fd7e124c6a34 100644 --- a/src/content/docs/en/guides/internationalization.mdx +++ b/src/content/docs/en/guides/internationalization.mdx @@ -1,5 +1,5 @@ --- -title: Internationalization +title: Internationalization (i18n) Routing description: Learn how to use i18n routing in Astro. i18nReady: false --- @@ -7,92 +7,97 @@ i18nReady: false import { FileTree } from '@astrojs/starlight/components'; import Since from '~/components/Since.astro' -Astro's internationalization (i18n) features allow you to adapt your project for an international audience. +Astro’s internationalization (i18n) features allow you to adapt your project for an international audience. This routing API helps you generate, use, and verify the URLs that your multi-language site produces. +Astro's i18n routing allows you to bring your multilingual content with support for configuring a default language, computing relative page URLs, and accepting preferred languages provided by your visitor's browser. You can also specify fallback languages on a per-language basis so that your visitors can always be directed to existing content on your site. -## i18n Routing +## Routing Logic -

+Astro uses a [middleware](/en/guides/middleware/) to implement its routing logic. This middleware function is placed in the [first position](/en/guides/middleware/#chaining-middleware) where it awaits every `Response` coming from any additional middleware and each page route before finally executing its own logic. -Astro's i18n routing allows you to add your multilingual content with support for configuring a default language, computing relative page URLs, and accepting preferred languages provided by your visitor's browser. You can also specify fallback languages on a per-language basis so that your visitors can always be directed to existing content on your site. +This means that operations (e.g. redirects) from your own middleware and your page logic are run first, your routes are rendered, and then the i18n middleware performs its own actions such as verifying that a localized URL corresponds to a valid route. -This routing API helps you generate, use, and verify the URLs that your multi-language site produces. Check back and update regularly for the latest new features as this API continues to develop! +You can also choose to [add your own i18n logic in addition to or instead of Astro's i18n middleware](#manual), giving you even more control over your routes while still having access to the `astro:i18n` helper functions. -### Configure i18n routing +## Configure i18n routing -1. Enable the routing option by adding an `i18n` object to your Astro configuration with a [default location (`defaultLocale`) and a list of all languages to support (`locales`)](#defaultlocale-and-locales): +Both a default language ([`defaultLocale`](/en/reference/configuration-reference/#i18ndefaultlocale)) and a list of all supported languages ([`locales`](/en/reference/configuration-reference/#i18nlocales)) must be specified in an `i18n` configuration object. Additionally, you can configure more specific routing and fallback behavior to match your desired URLs. - ```js title="astro.config.mjs" - import { defineConfig } from "astro/config" - export default defineConfig({ - i18n: { - defaultLocale: "en", - locales: ["en", "es", "pt-br"] - } - }) - ``` - -2. Choose and configure a [`routing`](#routing) based on the desired URL path for your `defaultLocale`: +```js title="astro.config.mjs" +import { defineConfig } from "astro/config" +export default defineConfig({ + i18n: { + defaultLocale: "en", + locales: ["es", "en", "pt-br"], + } +}) +``` - - `"prefixDefaultLocale: false"` (default): URLs in your default language will **not** have a `/[locale]/` prefix. All other locales will. +### Create localized folders - - `"prefixDefaultLocale: true"`: All URLs, including your default language, will have a `/[locale]/` prefix. +Organize your content folders with localized content by language. Create individual `/[locale]/` folders anywhere within `src/pages/` and Astro's [file-based routing](/en/guides/routing/) will create your pages at corresponding URL paths. - ```js title="astro.config.mjs" ins={7} - import { defineConfig } from "astro/config" - export default defineConfig({ - i18n: { - defaultLocale: "en", - locales: ["es", "en", "fr"], - routing: { - prefixDefaultLocale: false - } - } - }) - ``` +Your folder names must match the items in `locales` exactly. Include a localized folder for your `defaultLocale` only if you configure `prefixDefaultLocale: true` to show a localized URL path for your default language (e.g. /en/about/). -3. Organize your content folders with localized content by language. Your folder names must match the items in `locales` exactly, and your folder organization must match the URL paths chosen for your [`routing`](#routing). + +- src + - pages + - about.astro + - index.astro + - es + - about.astro + - index.astro + - pt-br + - about.astro + - index.astro + - Include a localized folder for your `defaultLocale` only if you configure `prefixDefaultLocale: true` to show a localized URL path. +:::note +The localized folders do not need to be at the root of the `/pages/` folder. +::: - - - src - - pages - - about.astro - - index.astro - - es - - about.astro - - index.astro - - pt-br - - about.astro - - index.astro - - :::note - The localized folders do not need to be at the root of the `/pages/` folder. - - Create individual `/[locale]/` folders anywhere within `src/pages/` and Astro's [file-based routing](/en/guides/routing/) will create your pages at corresponding URL paths. - ::: - -4. With i18n routing configured, you can now compute links to pages within your site using the [`getRelativeLocaleURL()`](#getrelativelocaleurl) helper available from the [`astro:i18n` module](#virtual-module-astroi18n). This will always provide the correct, localized route and can help you correctly use, or check, URLs on your site. You can also still write the links manually. +### Create links - ```astro title="src/pages/es/index.astro" - --- - import { getRelativeLocaleUrl } from 'astro:i18n'; +With i18n routing configured, you can now compute links to pages within your site using the helper functions such as [`getRelativeLocaleURL()`](/en/reference/api-reference/#getrelativelocaleurl) available from the [`astro:i18n` module](/en/reference/api-reference/#internationalization-astroi18n). These generated links will always provide the correct, localized route and can help you correctly use, or check, URLs on your site. - // defaultLocale is "es" - const aboutURL=getRelativeLocaleUrl("es", "about"); - --- +You can also still write the links manually. - ¡Vamos! - Blog - Acerca - ``` +```astro title="src/pages/es/index.astro" +--- +import { getRelativeLocaleUrl } from 'astro:i18n'; -### `routing` +// defaultLocale is "es" +const aboutURL=getRelativeLocaleUrl("es", "about"); +--- -Astro's built-in file-based routing automatically creates URL routes for you based on your file structure within `src/pages/`. When you configure i18n routing, the `routing` value now allows you to specify your file structure (and corresponding URL paths generated) in order to use helper functions to generate, use, and verify the routes in your project. +¡Vamos! +Blog +Acerca +``` + +## `routing` + +Astro's built-in file-based routing automatically creates URL routes for you based on your file structure within `src/pages/`. + +When you configure i18n routing, information about this file structure (and the corresponding URL paths generated) is available to the i18n helper functions so they can generate, use, and verify the routes in your project. Many of these options can be used together for even more customization and per-language flexibility. + +You can even choose to [implement your own routing logic manually](#manual) for even greater control. + +### `prefixDefaultLocale` + +

+ +This routing option defines whether or not your default language's URLs should use a language prefix (e.g. `/en/about/`). + +All non-default supported languages **will** use a localized prefix (e.g. `/fr/` or `/french/`) and content files must be located in appropriate folders. This configuration option allows you to specify whether your default language should also follow a localized URL structure. + +This setting also determines where the page files for your default language must exist (e.g. `src/pages/about/` or `src/pages/en/about`) as the file structure and URL structure must match for all languages. + +- `"prefixDefaultLocale: false"` (default): URLs in your default language will **not** have a `/[locale]/` prefix. All other locales will. + +- `"prefixDefaultLocale: true"`: All URLs, including your default language, will have a `/[locale]/` prefix. #### `prefixDefaultLocale: false` @@ -110,11 +115,23 @@ export default defineConfig({ }) ``` -This is the **default** value. Set this option when URLs in your default language will **not** have a `/[locale]/` prefix and files in your default language exist at the root of `src/pages/`. +This is the **default** value. Set this option when URLs in your default language will **not** have a `/[locale]/` prefix and files in your default language exist at the root of `src/pages/`: -- `src/pages/blog.astro` will produce the route `example.com/blog/` -- `src/pages/fr/blog.astro` will produce the route `example.com/fr/blog/` -- If there is no file at `src/pages/es/blog.astro`, then the route `example.com/es/blog/` will 404 unless you specify a [fallback strategy](#fallback). + + - src + - pages + - about.astro + - index.astro + - es + - about.astro + - index.astro + - fr + - about.astro + - index.astro + + +- `src/pages/about.astro` will produce the route `example.com/about/` +- `src/pages/fr/about.astro` will produce the route `example.com/fr/about/` #### `prefixDefaultLocale: true` @@ -149,9 +166,9 @@ Set this option when all routes will have their `/locale/` prefix in their URL a - index.astro -- URLs without a locale prefix, (e.g. `example.com/blog/`) will return a 404 (not found) status code. +- URLs without a locale prefix, (e.g. `example.com/about/`) will return a 404 (not found) status code unless you specify a [fallback strategy](#fallback). -#### `redirectToDefaultLocale` +### `redirectToDefaultLocale`

@@ -161,80 +178,75 @@ Setting `prefixDefaultLocale: true` will also automatically set `redirectToDefau You can opt out of this behavior by [setting `redirectToDefaultLocale: false`](/en/reference/configuration-reference/#i18nroutingredirecttodefaultlocale). This allows you to have a site home page that exists outside of your configured locale folder structure. -#### `domains` (experimental) -

+### `manual` -This routing option allows you to customize your domains on a per-language basis for `server` rendered projects using the [`@astrojs/node`](/en/guides/integrations-guide/node/) or [`@astrojs/vercel`](/en/guides/integrations-guide/vercel/) adapter with a `site` configured. +

-To enable this in your project, [configure i18n routing](#configure-i18n-routing) with your preferences if you have not already done so. Then, set the `experimental.i18nDomains` flag to `true` and add `i18n.domains` to map any of your supported `locales` to custom URLs: +When this option is enabled, Astro will **disable** its i18n middleware so that you can implement your own custom logic. No other `routing` options (e.g. `prefixDefaultLocale`) may be configured with `routing: "manual"`. -```js title="astro.config.mjs" {3-7} ins={14-21} +You will be responsible for writing your own routing logic, or [executing Astro's i18n middleware manually](#middleware-function) alongside your own. + +```js title="astro.config.mjs" import { defineConfig } from "astro/config" export default defineConfig({ - site: "https://example.com", - output: "server", // required, with no prerendered pages - adapter: node({ - mode: 'standalone', - }), i18n: { defaultLocale: "en", - locales: ["es", "en", "fr", "ja"], - routing: { - prefixDefaultLocale: false - }, - domains: { - fr: "https://fr.example.com", - es: "https://example.es" - } - }, - experimental: { - i18nDomains: true + locales: ["es", "en", "fr"], + routing: "manual" } }) ``` -All non-mapped `locales` will follow your `prefixDefaultLocales` configuration. However, even if this value is `false`, page files for your `defaultLocale` must also exist within a localized folder. For the configuration above, an `/en/` folder is required. - -With the above configuration: - -- The file `/fr/about.astro` will create the URL `https://fr.example.com/about`. -- The file `/es/about.astro` will create the URL `https://example.es/about`. -- The file `/ja/about.astro` will create the URL `https://example.com/ja/about`. -- The file `/en/about.astro` will create the URL `https://example.com/about`. - -The above URLs will also be returned by the `getAbsoluteLocaleUrl()` and `getAbsoluteLocaleUrlList()` functions. -##### Limitations - -This feature has some restrictions: -- The `site` option is mandatory. -- The `output` option must be set to `"server"`. -- There cannot be any individual prerendered pages. -- The adapter feature [`functionPerRoute`](/en/reference/adapter-reference/#functionperroute) is not supported. +Astro provides helper functions for your middleware so you can control your own default routing, exceptions, fallback behavior, error catching, etc: [`redirectToDefaultLocale()`](/en/reference/api-reference/#redirecttodefaultlocale), [`notFound()`](/en/reference/api-reference/#notfound), and [`redirectToFallback()`](/en/reference/api-reference/#redirecttofallback): -Astro relies on the following headers in order to support the feature: -- [`X-Forwarded-Host`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host) and [`Host`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host). Astro will use the former, and if not present, will try the latter. -- [`X-Forwarded-Proto`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto) and [`URL#protocol`](https://developer.mozilla.org/en-US/docs/Web/API/URL/protocol) of the server request. -Make sure that your server proxy/hosting platform is able to provide this information. Failing to retrieve these headers will result in a 404 (status code) page. +```js title="src/middleware.js" +import { defineMiddleware } from "astro:middleware"; +import { redirectToDefaultLocale } from "astro:i18n"; // function available with `manual` routing +export const onRequest = defineMiddleware(async (ctx, next) => { + if (ctx.url.startsWith("/about")) { + return next(); + } else { + return redirectToDefaultLocale(302); + } +}) +``` -#### Routing logic +#### middleware function -Astro uses a [middleware](/en/guides/middleware/) to implement its routing logic. This middleware function is placed in the [first position](/en/guides/middleware/#chaining-middleware) where it awaits every `Response` coming from any additional middleware and each page route before finally executing its own logic. +The [`middleware`](#middleware-function) function manually creates Astro's i18n middleware. This allows you to extend Astro's i18n routing instead of completely replacing it. -This means that operations (e.g. redirects) from your own middleware and your page logic are run first, your routes are rendered, and then the i18n middleware performs its own actions such as verifying that a localized URL corresponds to a valid route. +You can run `middleware` with [routing options](#routing) in combination with your own middleware, using the [`sequence`](/en/reference/api-reference/#sequence) utility to determine the order: -### `defaultLocale` and `locales` +```js title="src/middleware.js" +import {defineMiddleware, sequence} from "astro:middleware"; +import { middleware } from "astro:i18n"; // Astro's own i18n routing config -Both a default language ([`defaultLocale`](/en/reference/configuration-reference/#i18ndefaultlocale)) and a list of all supported languages ([`locales`](/en/reference/configuration-reference/#i18nlocales)) must be specified in your `i18n` routing configuration. - -Each entry in the `locales` configuration array must be either a string (e.g. `"fr"`, `"pt-br"`) or a [custom locale path](#custom-locale-paths). `locales` may contain a combination of strings and custom paths. +export const userMiddleware = defineMiddleware(async (ctx, next) => { + // this response might come from Astro's i18n middleware, and it might return a 404 + const response = await next(); + // the /about page is an exception and we want to render it + if (ctx.url.startsWith("/about")) { + return new Response("About page", { + status: 200 + }); + } else { + return response; + } +}); -Your `/[locale]/` folder names must match exactly the `locale`s in the list (either the string or the `path` value), and your [routing](#routing) configuration must correspond to whether or not you have a localized folder for your default language. Every other supported language must have its own localized folder. -Depending on your deploy host, you may discover transformations in URL paths, so check your deployed site to determine the best syntax for your `locale` values. +export const onRequest = sequence( + userMiddleware, + middleware({ + redirectToDefaultLocale: false, + prefixDefaultLocale: true + }) +) +``` -### Custom locale paths +## Custom locale paths In addition to defining your site's supported `locales` as strings (e.g. "en", "pt-br"), Astro also allows you to map an arbitrary number of [browser-recognized language `codes`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language#syntax) to a custom URL `path`. While locales can be strings of any format as long as they correspond to your project folder structure, `codes` must follow the browser's accepted syntax. @@ -259,9 +271,9 @@ export default defineConfig({ }) ``` -When using functions from the [`astro:i18n` virtual module](#virtual-module-astroi18n) to compute valid URL paths based on your configuration (e.g. `getRelativeLocaleUrl()`), [use the `path` as the value for `locale`](#generating-urls-from-custom-paths). +When using functions from the [`astro:i18n` virtual module](/en/reference/api-reference/#internationalization-astroi18n) to compute valid URL paths based on your configuration (e.g. `getRelativeLocaleUrl()`), [use the `path` as the value for `locale`](/en/reference/api-reference/#getlocalebypath). -### Browser language detection +## Browser language detection Astro’s i18n routing allows you to access two properties for browser language detection in pages rendered on demand: `Astro.preferredLocale` and `Astro.preferredLocaleList`. All pages, including static prerendered pages, have access to `Astro.currentLocale`. @@ -275,7 +287,7 @@ These combine the browser's `Accept-Language` header, and your `locales` (string In order to successfully match your visitors' preferences, provide your `codes` using the same pattern [used by the browser](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language#syntax). -### Fallback +## Fallback Astro's i18n routing allows you to configure a **fallback routing strategy**. When a page in one language doesn't exist (e.g. a page that is not yet translated), instead of displaying a 404 page, you can redirect a user from one locale to another on a per-language basis. This is useful when you do not yet have a page for every route, but you want to still provide some content to your visitors. @@ -296,163 +308,63 @@ export default defineConfig({ Astro will ensure that a page is built in `src/pages/fr` for every page that exists in `src/pages/es/`. If the page does not already exist, then a page with a redirect to the corresponding `es` route will be created. -## Virtual module `astro:i18n` - -This module provides functions that can help you create URLs using your project's configured locales. - -Creating routes for your project with the i18n router will depend on certain configuration values you have set that affect your page routes. When creating routes with these functions, be sure to take into account your individual settings for: +## `domains` (experimental) -- [`base`](/en/reference/configuration-reference/#base) -- [`trailingSlash`](/en/reference/configuration-reference/#trailingslash) -- [`build.format`](/en/reference/configuration-reference/#buildformat) -- [`site`](/en/reference/configuration-reference/#site) - -Also, note that the returned URLs created by these functions for your `defaultLocale` will reflect your `i18n.routing` configuration. - -URLs created when `prefixDefaultLocale: true` is configured will include a `/lang/` path in the URL. URLs created with `prefixDefaultLocale: false` will not include a language prefix. - -### `getRelativeLocaleUrl()` - -`getRelativeLocaleUrl(locale: string, path: string, options?: GetLocaleOptions): string` - -Use this function to retrieve a relative path for a locale. If the locale doesn't exist, Astro throws an error. - -```astro ---- -getRelativeLocaleUrl("fr"); -// returns /fr - -getRelativeLocaleUrl("fr", ""); -// returns /fr - -getRelativeLocaleUrl("fr", "getting-started"); -// returns /fr/getting-started - -getRelativeLocaleUrl("fr_CA", "getting-started", { - prependWith: "blog" -}); -// returns /blog/fr-ca/getting-started - -getRelativeLocaleUrl("fr_CA", "getting-started", { - prependWith: "blog", - normalizeLocale: false -}); -// returns /blog/fr_CA/getting-started ---- -``` - -### `getAbsoluteLocaleUrl()` - -`getAbsoluteLocaleUrl(locale: string, path: string, options?: GetLocaleOptions): string` - - -Use this function to retrieve an absolute path for a locale when [`site`] has a value. If [`site`] isn't configured, the function returns a relative URL. If the locale doesn't exist, Astro throws an error. - - -```astro title="src/pages/index.astro" ---- -// If `site` is set to be `https://example.com` - -getAbsoluteLocaleUrl("fr"); -// returns https://example.com/fr - -getAbsoluteLocaleUrl("fr", ""); -// returns https://example.com/fr - -getAbsoluteLocaleUrl("fr", "getting-started"); -// returns https://example.com/fr/getting-started - -getAbsoluteLocaleUrl("fr_CA", "getting-started", { - prependWith: "blog" -}); -// returns https://example.com/blog/fr-ca/getting-started - -getAbsoluteLocaleUrl("fr_CA", "getting-started", { - prependWith: "blog", - normalizeLocale: false -}); -// returns https://example.com/blog/fr_CA/getting-started ---- -``` - -### `getRelativeLocaleUrlList()` - -Use this like [`getRelativeLocaleUrl`](#getrelativelocaleurl) to return a list of relative paths for all the locales. - - -`getRelativeLocaleUrlList(path?: string, options?: GetLocaleOptions): string[]` - -### `getAbsoluteLocaleUrlList()` - -`getAbsoluteLocaleUrlList(path?: string, options?: GetLocaleOptions): string[]` - -Use this like [`getAbsoluteLocaleUrl`](#getabsolutelocaleurl) to return a list of absolute paths for all the locales. - -### `getPathByLocale(locale: string): string` - -A function that returns the `path` associated to one or more `codes` when [custom locale paths](#custom-locale-paths) are configured. - -### Generating URLs from custom paths +

-When a `locale` is a custom path, use the `path` as the value for `locale`. +This routing option allows you to customize your domains on a per-language basis for `server` rendered projects using the [`@astrojs/node`](/en/guides/integrations-guide/node/) or [`@astrojs/vercel`](/en/guides/integrations-guide/vercel/) adapter with a `site` configured. -For example, use `french` in the i18n helper functions for the `locales` configuration below: +To enable this in your project, [configure i18n routing](#configure-i18n-routing) with your preferences if you have not already done so. Then, set the `experimental.i18nDomains` flag to `true` and add `i18n.domains` to map any of your supported `locales` to custom URLs: -```js -locales: ["es", "en", { - path: "french", - codes: ["fr", "fr-BR", "fr-CA"] -}], +```js title="astro.config.mjs" {3-7} ins={14-21} +import { defineConfig } from "astro/config" +export default defineConfig({ + site: "https://example.com", + output: "server", // required, with no prerendered pages + adapter: node({ + mode: 'standalone', + }), + i18n: { + defaultLocale: "en", + locales: ["es", "en", "fr", "ja"], + routing: { + prefixDefaultLocale: false + }, + domains: { + fr: "https://fr.example.com", + es: "https://example.es" + } + }, + experimental: { + i18nDomains: true + } +}) ``` -```astro title="src/pages/index.astro" ---- -import { getPathByLocale, getRelativeLocaleUrl, getLocaleByPath } from "astro:i18n"; +All non-mapped `locales` will follow your `prefixDefaultLocales` configuration. However, even if this value is `false`, page files for your `defaultLocale` must also exist within a localized folder. For the configuration above, an `/en/` folder is required. -getRelativeLocaleUrl("french", "blog"); // returns /french/blog ---- -``` -Note that other `astro:i18n` functions will return the following results for the same configuration: - -```astro title="src/pages/index.astro" ---- -getPathByLocale("fr"); // returns "french" -getPathByLocale("fr-CA"); // returns "french" -getLocaleByPath("french"); // returns "fr" because that's the first code configured ---- -``` +With the above configuration: -### `getLocaleByPath(path: string): string` +- The file `/fr/about.astro` will create the URL `https://fr.example.com/about`. +- The file `/es/about.astro` will create the URL `https://example.es/about`. +- The file `/ja/about.astro` will create the URL `https://example.com/ja/about`. +- The file `/en/about.astro` will create the URL `https://example.com/about`. -A function that returns the `code` associated to a locale `path`. +The above URLs will also be returned by the `getAbsoluteLocaleUrl()` and `getAbsoluteLocaleUrlList()` functions. -### Retrieve the locale for a custom path +#### Limitations -Given a custom path configured with multiple `codes`, the function will return the **first** code configured: +This feature has some restrictions: +- The `site` option is mandatory. +- The `output` option must be set to `"server"`. +- There cannot be any individual prerendered pages. +- The adapter feature [`functionPerRoute`](/en/reference/adapter-reference/#functionperroute) is not supported. -```js -// astro.config.mjs -import {defineConfig} from "astro/config" -export default defineConfig({ - i18n: { - defaultLocale: "en", - locales: ["en", "es", "fr", { - path: "portugues", - codes: ["pt-AO", "pt", "pt-BR"] - }] - } -}) -``` +Astro relies on the following headers in order to support the feature: +- [`X-Forwarded-Host`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host) and [`Host`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host). Astro will use the former, and if not present, will try the latter. +- [`X-Forwarded-Proto`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto) and [`URL#protocol`](https://developer.mozilla.org/en-US/docs/Web/API/URL/protocol) of the server request. -```astro ---- -// src/pages/index.astro -import { getLocaleByPath } from "astro:i18n"; -console.log(getLocaleByPath("en")) // will log "en" -console.log(getLocaleByPath("fr")) // will log "fr" -console.log(getLocaleByPath("portugues")) // will log "pt-AO" ---- -``` +Make sure that your server proxy/hosting platform is able to provide this information. Failing to retrieve these headers will result in a 404 (status code) page. [`site`]: /en/reference/configuration-reference/#site [`i18n.locales`]: /en/reference/configuration-reference/#i18nlocales diff --git a/src/content/docs/en/reference/api-reference.mdx b/src/content/docs/en/reference/api-reference.mdx index 001367cdf1595..231c7b600f318 100644 --- a/src/content/docs/en/reference/api-reference.mdx +++ b/src/content/docs/en/reference/api-reference.mdx @@ -1395,6 +1395,282 @@ This function can be used by integrations/adapters to programmatically execute t A low-level API that takes in any value and tries to return a serialized version (a string) of it. If the value cannot be serialized, the function will throw a runtime error. +## Internationalization (`astro:i18n`) + +

+ +This module provides functions to help you create URLs using your project's configured locales. + +Creating routes for your project with the i18n router will depend on certain configuration values you have set that affect your page routes. When creating routes with these functions, be sure to take into account your individual settings for: + +- [`base`](/en/reference/configuration-reference/#base) +- [`trailingSlash`](/en/reference/configuration-reference/#trailingslash) +- [`build.format`](/en/reference/configuration-reference/#buildformat) +- [`site`](/en/reference/configuration-reference/#site) + +Also, note that the returned URLs created by these functions for your `defaultLocale` will reflect your `i18n.routing` configuration. + +For features and usage examples, [see our i18n routing guide](/en/guides/internationalization/). + +### `getRelativeLocaleUrl()` + +`getRelativeLocaleUrl(locale: string, path?: string, options?: GetLocaleOptions): string` + +Use this function to retrieve a relative path for a locale. If the locale doesn't exist, Astro throws an error. + +```astro +--- +getRelativeLocaleUrl("fr"); +// returns /fr + +getRelativeLocaleUrl("fr", ""); +// returns /fr + +getRelativeLocaleUrl("fr", "getting-started"); +// returns /fr/getting-started + +getRelativeLocaleUrl("fr_CA", "getting-started", { + prependWith: "blog" +}); +// returns /blog/fr-ca/getting-started + +getRelativeLocaleUrl("fr_CA", "getting-started", { + prependWith: "blog", + normalizeLocale: false +}); +// returns /blog/fr_CA/getting-started +--- +``` + +### `getAbsoluteLocaleUrl()` + +`getAbsoluteLocaleUrl(locale: string, path: string, options?: GetLocaleOptions): string` + +Use this function to retrieve an absolute path for a locale when [`site`] has a value. If [`site`] isn't configured, the function returns a relative URL. If the locale doesn't exist, Astro throws an error. + + +```astro title="src/pages/index.astro" +--- +// If `site` is set to be `https://example.com` + +getAbsoluteLocaleUrl("fr"); +// returns https://example.com/fr + +getAbsoluteLocaleUrl("fr", ""); +// returns https://example.com/fr + +getAbsoluteLocaleUrl("fr", "getting-started"); +// returns https://example.com/fr/getting-started + +getAbsoluteLocaleUrl("fr_CA", "getting-started", { + prependWith: "blog" +}); +// returns https://example.com/blog/fr-ca/getting-started + +getAbsoluteLocaleUrl("fr_CA", "getting-started", { + prependWith: "blog", + normalizeLocale: false +}); +// returns https://example.com/blog/fr_CA/getting-started +--- +``` + +### `getRelativeLocaleUrlList()` + +`getRelativeLocaleUrlList(path?: string, options?: GetLocaleOptions): string[]` + + +Use this like [`getRelativeLocaleUrl`](#getrelativelocaleurl) to return a list of relative paths for all the locales. + + +### `getAbsoluteLocaleUrlList()` + +`getAbsoluteLocaleUrlList(path?: string, options?: GetLocaleOptions): string[]` + +Use this like [`getAbsoluteLocaleUrl`](/en/guides/internationalization/#custom-locale-paths) to return a list of absolute paths for all the locales. + +### `getPathByLocale()` + +`getPathByLocale(locale: string): string` + +A function that returns the `path` associated to one or more `codes` when [custom locale paths](/en/guides/internationalization/#custom-locale-paths) are configured. + +```js title="astro.config.mjs" +export default defineConfig({ + i18n: { + locales: ["es", "en", { + path: "french", + codes: ["fr", "fr-BR", "fr-CA"] + }] + } +}) +``` + +```astro title="src/pages/index.astro" +--- +getPathByLocale("fr"); // returns "french" +getPathByLocale("fr-CA"); // returns "french" +--- +``` + +### `getLocaleByPath` + + `getLocaleByPath(path: string): string` + +A function that returns the `code` associated to a locale `path`. + +```js title="astro.config.mjs" +export default defineConfig({ + i18n: { + locales: ["es", "en", { + path: "french", + codes: ["fr", "fr-BR", "fr-CA"] + }] + } +}) +``` + +```astro title="src/pages/index.astro" +--- +getLocaleByPath("french"); // returns "fr" because that's the first code configured +--- +``` + +### `redirectToDefaultLocale()` + +`redirectToDefaultLocale(context: APIContext, statusCode?: ValidRedirectStatus): Promise` + +

+ +:::note +Available only when `i18n.routing` is set to `"manual"` +::: + +A function that returns a `Response` that redirects to the `defaultLocale` configured. It accepts an optional valid redirect status code. + +```js title="middleware.js" +import { defineMiddleware } from "astro:middleware"; +import { redirectToDefaultLocale } from "astro:i18n"; + +export const onRequest = defineMiddleware((context, next) => { + if (context.url.pathname.startsWith("/about")) { + return next(); + } else { + return redirectToDefaultLocale(context, 302); + } +}) +``` + +### `redirectToFallback()` + +`redirectToFallback(context: APIContext, response: Response): Promise` + +

+ +:::note +Available only when `i18n.routing` is set to `"manual"` +::: + +A function that allows you to use your [`i18n.fallback` configuration](/en/reference/configuration-reference/#i18nfallback) in your own middleware. + +```js title="middleware.js" +import { defineMiddleware } from "astro:middleware"; +import { redirectToFallback } from "astro:i18n"; + +export const onRequest = defineMiddleware(async (context, next) => { + const response = await next(); + if (response.status >= 300) { + return redirectToFallback(context, response) + } + return response; +}) +``` + +### `notFound()` + +`notFound(context: APIContext, response: Response): Promise` + +

+ +:::note +Available only when `i18n.routing` is set to `"manual"` +::: + +Use this function in your routing middleware to return a 404 when: +- the current path isn't a root. e.g. `/` or `/` +- the URL doesn't contain a locale + +When a `Response` is passed, the new `Response` emitted by this function will contain the same headers of the original response. + +```js title="middleware.js" +import { defineMiddleware } from "astro:middleware"; +import { notFound } from "astro:i18n"; + +export const onRequest = defineMiddleware((context, next) => { + const pathNotFound = notFound(context); + if (pathNotFound) { + return pathNotFound; + } + return next(); +}) +``` + +### `middleware()` + +`middleware(options: { prefixDefaultLocale: boolean, redirectToDefaultLocale: boolean })` + +

+ +:::note +Available only when `i18n.routing` is set to `"manual"` +::: + +A function that allows you to programmatically create the Astro i18n middleware. + +This is use useful when you still want to use the default i18n logic, but add only a few exceptions to your website. + +```js title="middleware.js" +import { middleware } from "astro:i18n"; +import { sequence, defineMiddleware } from "astro:middleware"; + +const customLogic = defineMiddleware(async (context, next) => { + const response = await next(); + + // Custom logic after resolving the response. + // It's possible to catch the response coming from Astro i18n middleware. + + return response; +}); + +export const onRequest = sequence(customLogic, middleware({ + prefixDefaultLocale: true, + redirectToDefaultLocale: false +})) +``` + +### `requestHasLocale()` + +`requestHasLocale(context: APIContext): boolean` + +

+ +:::note +Available only when `i18n.routing` is set to `"manual"` +::: + +Checks whether the current URL contains a configured locale. Internally, this function will use `APIContext#url.pathname`. + +```js title="middleware.js" +import { defineMiddleware } from "astro:middleware"; +import { requestHasLocale } from "astro:i18n"; + +export const onRequest = defineMiddleware(async (context, next) => { + if (requestHasLocale(context)) { + return next(); + } + return new Response("Not found", { status: 404 }); +}) +``` ## Built-in Components diff --git a/src/content/docs/en/reference/configuration-reference.mdx b/src/content/docs/en/reference/configuration-reference.mdx index d0de45d7d9c08..7c5e42ead745a 100644 --- a/src/content/docs/en/reference/configuration-reference.mdx +++ b/src/content/docs/en/reference/configuration-reference.mdx @@ -1376,7 +1376,7 @@ export default defineConfig({ }); ``` -Both page routes built and URLs returned by the `astro:i18n` helper functions [`getAbsoluteLocaleUrl()`](/en/guides/internationalization/#getabsolutelocaleurl) and [`getAbsoluteLocaleUrlList()`](/en/guides/internationalization/#getabsolutelocaleurllist) will use the options set in `i18n.domains`. +Both page routes built and URLs returned by the `astro:i18n` helper functions [`getAbsoluteLocaleUrl()`](/en/reference/api-reference/#getabsolutelocaleurl) and [`getAbsoluteLocaleUrlList()`](/en/reference/api-reference/#getabsolutelocaleurllist) will use the options set in `i18n.domains`. See the [Internationalization Guide](/en/guides/internationalization/#domains-experimental) for more details, including the limitations of this experimental feature. diff --git a/src/content/docs/es/reference/configuration-reference.mdx b/src/content/docs/es/reference/configuration-reference.mdx index 92ed0b2444f86..7013b4453b2b4 100644 --- a/src/content/docs/es/reference/configuration-reference.mdx +++ b/src/content/docs/es/reference/configuration-reference.mdx @@ -1306,5 +1306,5 @@ export default defineConfig({ }, }); ``` -Ambas rutas de página construidas y URLs devueltas por las funciones auxiliares `astro:i18n` [`getAbsoluteLocaleUrl()`](/es/guides/internationalization/#getabsolutelocaleurl) y [`getAbsoluteLocaleUrlList()`](/es/guides/internationalization/#getabsolutelocaleurllist) utilizarán las opciones establecidas en `i18n.domains`. +Ambas rutas de página construidas y URLs devueltas por las funciones auxiliares `astro:i18n` `getAbsoluteLocaleUrl()` y `getAbsoluteLocaleUrlList()` utilizarán las opciones establecidas en `i18n.domains`. Ver la [Guía de Internacionalización](/es/guides/internationalization/#domains-experimental) para más detalles, incluyendo las limitaciones de esta característica experimental. diff --git a/src/content/docs/ja/reference/configuration-reference.mdx b/src/content/docs/ja/reference/configuration-reference.mdx index f875eb6b14de6..da22b6961832e 100644 --- a/src/content/docs/ja/reference/configuration-reference.mdx +++ b/src/content/docs/ja/reference/configuration-reference.mdx @@ -1223,6 +1223,6 @@ export default defineConfig({ }); ``` -作成されたページルートと、`astro:i18n`のヘルパー関数[`getAbsoluteLocaleUrl()`](/ja/guides/internationalization/#getabsolutelocaleurl)および[`getAbsoluteLocaleUrlList()`](/ja/guides/internationalization/#getabsolutelocaleurllist)から返されたURLは、ともに`i18n.domains`に設定されたオプションを使用します。 +作成されたページルートと、`astro:i18n`のヘルパー関数[`getAbsoluteLocaleUrl()`](/ja/reference/api-reference/#getabsolutelocaleurl)および[`getAbsoluteLocaleUrlList()`](/ja/reference/api-reference/#getabsolutelocaleurllist)から返されたURLは、ともに`i18n.domains`に設定されたオプションを使用します。 この実験的機能の制限を含む詳しい情報については、[国際化ガイド](/ja/guides/internationalization/#domains-experimental)を参照してください。 diff --git a/src/content/docs/ko/guides/internationalization.mdx b/src/content/docs/ko/guides/internationalization.mdx index dc0c338413239..1654aef5d1fdd 100644 --- a/src/content/docs/ko/guides/internationalization.mdx +++ b/src/content/docs/ko/guides/internationalization.mdx @@ -21,7 +21,7 @@ Astro의 i18n 라우팅을 사용하면 기본 언어 구성, 상대 페이지 U ### i18n 라우팅 구성 -1. [기본 언어 (`defaultLocale`) 및 지원할 모든 언어 목록 (`locales`)](#defaultlocale-및-locales)을 사용하여 Astro 구성에 `i18n` 객체를 추가하여 라우팅 옵션을 활성화합니다. +1. [기본 언어 (`defaultLocale`) 및 지원할 모든 언어 목록 (`locales`)](/ko/reference/configuration-reference/#i18nlocales)을 사용하여 Astro 구성에 `i18n` 객체를 추가하여 라우팅 옵션을 활성화합니다. ```js title="astro.config.mjs" import { defineConfig } from 'astro/config'; diff --git a/src/content/docs/zh-cn/reference/configuration-reference.mdx b/src/content/docs/zh-cn/reference/configuration-reference.mdx index a0ff5803c9533..0f85c95ff739e 100644 --- a/src/content/docs/zh-cn/reference/configuration-reference.mdx +++ b/src/content/docs/zh-cn/reference/configuration-reference.mdx @@ -1338,6 +1338,6 @@ export default defineConfig({ }); ``` -`astro:i18n` 辅助函数 [`getAbsoluteLocaleUrl()`](/zh-cn/guides/internationalization/#getabsolutelocaleurl) 和 [`getAbsoluteLocaleUrlList()`](/zh-cn/guides/internationalization/#getabsolutelocaleurllist) 构建的页面路由和 URL 将使用 `i18n.domains` 中设置的选项。 +`astro:i18n` 辅助函数 `getAbsoluteLocaleUrl()` 和 `getAbsoluteLocaleUrlList()` 构建的页面路由和 URL 将使用 `i18n.domains` 中设置的选项。 查看 [国际化指南](/zh-cn/guides/internationalization/#domains-experimental) 以获取更多细节,包括这个实验性功能的限制。