From 81983494d6fc00d54d5209142167baa59c5a1389 Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Thu, 21 Dec 2023 13:49:24 +0000 Subject: [PATCH 1/5] rfc: i18n routing domain support --- proposals/0046-i18n-domain-support.md | 62 +++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 proposals/0046-i18n-domain-support.md diff --git a/proposals/0046-i18n-domain-support.md b/proposals/0046-i18n-domain-support.md new file mode 100644 index 00000000..c2c186a9 --- /dev/null +++ b/proposals/0046-i18n-domain-support.md @@ -0,0 +1,62 @@ +- Start Date: 2023/12/21 +- Reference Issues: +- Implementation PR: https://github.com/withastro/astro/pull/9143 + + +# Summary + +First-class support for domain support in i18n routing. + + +# Background & Motivation + +Websites that support internationalisation have different requirements. Among these requirements, there's the need to +have localised content under different subdomains or domains. + +# Goals + +- Support different domains, all driven by the same Astro project; +- Mix locales that require a different domain, with locales that don't require a different domain; + +# Non-Goals + +- Force a redirect to users +- Change website/domain based on the language of the user's browser + + +# Detailed Design + + +A feature that allows to support different domains for certain locales. + +Using the configuration `domains`, a user can specify which locales should benefit from a domain. This feature changes the behaviour of some of the APIs exported by the virtual module `astro:i18n`. + +```js +// astro.config.mjs +import {defineConfig} from "astro/config" +export default defineConfig({ + i18n: { + defaultLocaLe: 'en', + locales: ['en', 'es', 'pt_BR', 'pt', 'fr'], + domains: { + fr: "https://fr.example.com", + pt: "https://example.pt" + }, + routingStrategy: "domain" + } +}) +``` + +The following APIs will behave as follows: +- [`getRelativeLocaleUrl`](#getrelativelocaleurllocale-string-string): it won't prefix the locale to the URL. From `/en` to `/`; +- [`getAbsoluteLocaleUrl`](#getabsolutelocaleurllocale-string-string): it won't have the locale in the URL: From `example.com/fr` to `fr.example.com/`; + +Adapters must have the capabilities to redirect a user from one domain to another based on the domains configured. + +An adapter can signal Astro the feature support using the relative configuration: + +In order to support this feature, Astro needs to know the origin of the server (the domain where the server is hosted). To achieve this, Astro will rely on the following headers: +- [`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. + +If any of this information is missing, Astro won't be able to map the route. This will result in a 404. From b587d4395b901ba661f00205a3b6365e661b8fee Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Fri, 19 Jan 2024 15:12:04 +0000 Subject: [PATCH 2/5] address comments --- proposals/0046-i18n-domain-support.md | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/proposals/0046-i18n-domain-support.md b/proposals/0046-i18n-domain-support.md index c2c186a9..71e5cb0b 100644 --- a/proposals/0046-i18n-domain-support.md +++ b/proposals/0046-i18n-domain-support.md @@ -20,7 +20,7 @@ have localised content under different subdomains or domains. # Non-Goals -- Force a redirect to users +- Redirect users from a path website to a domain website - Change website/domain based on the language of the user's browser @@ -51,9 +51,26 @@ The following APIs will behave as follows: - [`getRelativeLocaleUrl`](#getrelativelocaleurllocale-string-string): it won't prefix the locale to the URL. From `/en` to `/`; - [`getAbsoluteLocaleUrl`](#getabsolutelocaleurllocale-string-string): it won't have the locale in the URL: From `example.com/fr` to `fr.example.com/`; -Adapters must have the capabilities to redirect a user from one domain to another based on the domains configured. +An adapter can signal Astro what kind of support has for this new feature: -An adapter can signal Astro the feature support using the relative configuration: +```js +export default function createIntegration() { + return { + name: '@matthewp/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: '@matthewp/my-adapter', + serverEntrypoint: '@matthewp/my-adapter/server.js', + supportedAstroFeatures: { + domains: 'experimental' // 'unsupported' | 'stable' | 'experimental' | 'deprecated' + } + }); + }, + }, + }; +} +``` In order to support this feature, Astro needs to know the origin of the server (the domain where the server is hosted). To achieve this, Astro will rely on the following headers: - [`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. From cc268a62b955791131e4504994823b2796e0ce85 Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Tue, 23 Jan 2024 11:33:54 +0000 Subject: [PATCH 3/5] add restrictions --- proposals/0046-i18n-domain-support.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/proposals/0046-i18n-domain-support.md b/proposals/0046-i18n-domain-support.md index 71e5cb0b..0ba1e7db 100644 --- a/proposals/0046-i18n-domain-support.md +++ b/proposals/0046-i18n-domain-support.md @@ -16,16 +16,24 @@ have localised content under different subdomains or domains. # Goals - Support different domains, all driven by the same Astro project; +- Configure some locales to use only path prefixes and some locales to use domains; - Mix locales that require a different domain, with locales that don't require a different domain; # Non-Goals - Redirect users from a path website to a domain website -- Change website/domain based on the language of the user's browser +- Change website/domain based on the language of the user's browser +- Support for static/hybrid output +- Offer the means to configure multiple domains for serverless hosts (Vercel, Netlify, etc.) # Detailed Design +There are some restrictions about how the feature will initially work: +- the feature works only with `output: "server"`, hence only in SSR; +- the presence of at least one pre-rendered route will cause a failure in the build; +- the option `base` is required, because Astro needs to know how to create absolute URLs for locales that aren't mapped to a domain; +- `functionPerRoute` isn't supported A feature that allows to support different domains for certain locales. From 0f39b43bbac42f1ad3913889c5cfce0eb9547ee9 Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Fri, 26 Jan 2024 12:17:36 +0000 Subject: [PATCH 4/5] Address feedback --- proposals/0046-i18n-domain-support.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/0046-i18n-domain-support.md b/proposals/0046-i18n-domain-support.md index 0ba1e7db..d7ed2659 100644 --- a/proposals/0046-i18n-domain-support.md +++ b/proposals/0046-i18n-domain-support.md @@ -32,7 +32,7 @@ have localised content under different subdomains or domains. There are some restrictions about how the feature will initially work: - the feature works only with `output: "server"`, hence only in SSR; - the presence of at least one pre-rendered route will cause a failure in the build; -- the option `base` is required, because Astro needs to know how to create absolute URLs for locales that aren't mapped to a domain; +- the option `site` is required, because Astro needs to know how to create absolute URLs for locales that aren't mapped to a domain; - `functionPerRoute` isn't supported A feature that allows to support different domains for certain locales. @@ -43,6 +43,8 @@ Using the configuration `domains`, a user can specify which locales should benef // astro.config.mjs import {defineConfig} from "astro/config" export default defineConfig({ + site: "https://example.com", + output: "server", i18n: { defaultLocaLe: 'en', locales: ['en', 'es', 'pt_BR', 'pt', 'fr'], @@ -55,9 +57,7 @@ export default defineConfig({ }) ``` -The following APIs will behave as follows: -- [`getRelativeLocaleUrl`](#getrelativelocaleurllocale-string-string): it won't prefix the locale to the URL. From `/en` to `/`; -- [`getAbsoluteLocaleUrl`](#getabsolutelocaleurllocale-string-string): it won't have the locale in the URL: From `example.com/fr` to `fr.example.com/`; +The functions [`getAbsoluteLocaleUrl`](#https://docs.astro.build/en/guides/internationalization/#getabsolutelocaleurl) and [getAbsoluteLocaleUrlList](https://docs.astro.build/en/guides/internationalization/#getabsolutelocaleurllist) - when building the Astro project - will generate URLs using the configured domains. For example, the URL `example.com/fr` will become `fr.example.com/`. An adapter can signal Astro what kind of support has for this new feature: From 776a14031901e8303b8b0536eb65a4aa531e59a5 Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Tue, 30 Jan 2024 09:21:52 +0000 Subject: [PATCH 5/5] make the example correct --- proposals/0046-i18n-domain-support.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/proposals/0046-i18n-domain-support.md b/proposals/0046-i18n-domain-support.md index d7ed2659..f7cb6552 100644 --- a/proposals/0046-i18n-domain-support.md +++ b/proposals/0046-i18n-domain-support.md @@ -41,7 +41,9 @@ Using the configuration `domains`, a user can specify which locales should benef ```js // astro.config.mjs -import {defineConfig} from "astro/config" +import {defineConfig} from "astro/config"; +import node from "@astrojs/node"; + export default defineConfig({ site: "https://example.com", output: "server", @@ -51,9 +53,11 @@ export default defineConfig({ domains: { fr: "https://fr.example.com", pt: "https://example.pt" - }, - routingStrategy: "domain" - } + } + }, + adapter: node({ + mode: "standalone" + }) }) ```