Closed ematipico closed 11 months ago
@ematipico
We landed to the conclusion that routing strategies should be applied only to pages: c93015d
This would solve most of the issues, but the routing is still pretty messed up which makes it hard to check. Especially the fallback part... I bet you saw the issues I opened.
I'll get to those issues, don't worry. It's completely fine to have issues during the experimental phase, and I thank you very much for being so adventurous to try this new feature.
@ematipico
We landed to the conclusion that routing strategies should be applied only to pages: c93015d
This would solve most of the issues, but the routing is still pretty messed up which makes it hard to check. Especially the fallback part... I bet you saw the issues I opened.
I'll get to those issues, don't worry. It's completely fine to have issues during the experimental phase, and I thank you very much for being so adventurous to try this new feature.
I was mentioning those as they prevent a lot of testing as they fail in many cases, but I know you'll get there :)
Oh, I might be adding a feature request or consideration at least.
If you want to add these tags, which are the i18n standard way of doing things you need all links, which you can get with the current APIs, but it becomes a pain to match those to the language that generated it.
Returning an array of value pairs or an object would be great. Mostly so you know which link corresponds to which locale.
I’ve seen several comments (1, 2, 3, 4, etc.) requesting that an Astro file render all locales
.
└── pages/
├── about.astro
└── index.astro
instead of having Astro files for every locale
.
└── pages/
├── about.astro
├── index.astro
├── es/
│ ├── about.astro
│ └── index.astro
└── fr/
├── about.astro
└── index.astro
to avoid code duplication and fetch data from APIs and content collections, while still supporting the unprefixed defaultLocale
@itsmatteomanf One question about your comment:
{
locales: [
{
path: 'it',
default: "it", // this is the one you want whenever you have to chose like a single value for the specific locale
lang: [ "it", "it-CH", "it-IT", "it-SM", "it-VA"] // these you use for like canonicals, matching routes, etc.
}
]
}
What's the different between path
and default
? How should I use default
and in which context?
@ematipico
What's the different between
path
anddefault
? How should I usedefault
and in which context?
path
is the actual URL path example.com/[lang]/blog
, default
is the default locale, it could be like it-CH
, in that example.
It's like that so that you know which is the canonical (if it were just one language) or which is the locale you set your HTML to, e.g. <html lang="<default>">...</html>
.
Thank you @itsmatteomanf. Now that I understand what's meant for, maybe we can directly use the lang
array. Since it's an array, we can leverage the order (from left to right), so we can also deliver a sense of priority of the languages needed by the user. This would be inline with how the Accept-Language
header works. What do you think?
Since it's an array, we can leverage the order (from left to right), so we can also deliver a sense of priority of the languages needed by the user.
Fine by me, @ematipico! I'm almost sure I wrote it somewhere, but I guess I didn't ahah
Maybe do expose that with a specific endpoint, just to make it clearer and easier, but not sure what scope and how big the APIs will be. It's kinda easy to do, anyway.
Some more feedback (you may have thought about it already).
English has two plural forms, but many languages have several. This is generally handled via a count
param to the translation helper, e.g. t('login.status', { count: myInt });
and the following translation data:
login:
heading: "Login statistics"
status:
# some languages would have additional plural forms here
one: "Last login ${count} day ago"
other: "Last login ${count} days ago"
Instead of having .astro
files, I'd recommend something like json
or yaml
.
Take some inspiration from the large localisation platforms:
how would a language-switcher look like with the current astro:i18n
api?
how would a language-switcher look like with the current
astro:i18n
api?
Depending on your environment, use the list APIs: https://docs.astro.build/en/guides/internationalization/#getrelativelocaleurllist
Then map the result into a new array where you add the label of each locale. Then you should have all the information for a drop-down.
Due to time and difficulty issues, we removed the domain support from this RFC. We will land domain support in Astro 4.* under a feature flag. https://github.com/withastro/roadmap/pull/734/commits/22d192b89b9b259d63410926a5612fdac145f99e
Calling for consensus for this RFC. The period will last for 3 days and if there's no objections, this RFC will be merged.
In https://github.com/withastro/roadmap/pull/734/commits/089253d317e4327ee4e3b93eb303ddc28859952b, I removed routingStrategy
in favour of:
{
routing: {
strategy: "pathname",
prefixDefaultLocale: true
}
}
As discussed and proposed in https://github.com/withastro/roadmap/pull/734#issuecomment-1799126771
Also, myself and Chris had a chat, we changed the shape slightly to align it with the current one, and take advantage of the zod .transform
function.
Looks good to me, @ematipico.
The only thing I don't see, but may be there just not explained fully, is a way to get all locales, in the more granular configuration option, with their URLs, even if they are repeated.
This is very useful for the link alternate i18n configurations (and possibly even for the sitemap plugin).
Looks good to me, @ematipico.
The only thing I don't see, but may be there just not explained fully, is a way to get all locales, in the more granular configuration option, with their URLs, even if they are repeated.
This is very useful for the link alternate i18n configurations (and possibly even for the sitemap plugin).
I'll be happy to add such APIs, could you propose something with the expected result? It would help to get the API right easily
Looks good to me, @ematipico. The only thing I don't see, but may be there just not explained fully, is a way to get all locales, in the more granular configuration option, with their URLs, even if they are repeated. This is very useful for the link alternate i18n configurations (and possibly even for the sitemap plugin).
I'll be happy to add such APIs, could you propose something with the expected result? It would help to get the API right easily
Sorry, was on mobile...
Given a config file like this:
// astro.config.mjs
import {defineConfig} from "astro/config"
export default defineConfig({
i18n: {
defaultLocale: 'en',
locales: ['en', 'es', 'fr', {
path: "portugues",
codes: ["pt", "pt-BR", "pt-AO"]
}]
}
})
Return something like this:
[
["en", "/blog"],
["es", "/es/blog"],
["fr", "/fr/blog"],
["pt", "/portugues/blog"],
["pt-BR", "/portugues/blog"],
["pt-AO", "/portugues/blog"]
]
Two issues I see, thinking about this now.
The current getRelativeLocaleUrlList()
and getAbsoluteLocaleUrlList()
don't associate a locale with the URL, making it hard to use in a <select>
with a value of the locale or assign a label to the URL (how do I know which is first and get the label? I know it's probably the order I defined them in, but it's not stored anywhere, apart from the config file), and that would apply for this API, too.
Maybe an array of objects here, e.g. { locale: "pt-BR", path: "portugues", url: "/portugues/blog" }
, is better?
And probably the same or similar in the other cases? 🤔
I'll have to think about it, and we can definitely land a new API after we merge the RFC, there's nothing to prevent us from doing so.
@ematipico Would be nice to have a feedback about code duplication (https://github.com/withastro/roadmap/pull/734#issuecomment-1817750144) as from a quick look on the RFC it's not clear to me how, after the implementation, the projects files should be structured, (I probably missed between the comments) is there a sample repo to showcase how the page structure will look like?
Thanks
@ematipico Would be nice to have a feedback about code duplication (#734 (comment)) as from a quick look on the RFC it's not clear to me how, after the implementation, the projects files should be structured, (I probably missed between the comments) is there a sample repo to showcase how the page structure will look like?
Thanks
The RFC is meant for routing and fallback, not content (labels, dictionaries, etc.). We wanted to keep the first round of implementation small and provide as many utilises as possible so the community can build around them. Let's remember that nothing prevents us from adding more features. In fact, we already have a few features that we will add after this first RFC is merged,
The fallback system is one of the most significant changes we added because it adds patterns that weren't possible in Astro core before. Once we deem that feature stable enough, we could use the same logic to generate pages to avoid code duplication.
@ematipico Thanks for the clarification
Oops didn't notice this is merged, but anyways my comments aren't urgent, just some questions that I wonder if it's a typo or not.
Hey folks,
I am quite late to the party but I am currently discovering Astro, and I got a good knowledge of Next.js behavior and recent changes regarding i18n, so I'd like to share some feedback after spending ~1h playing with Astro i18n setup and reading the guide :
the routing strategy is not super clearly documented yet, though the browser redirection section seems to implicitly mention that it's based on the Accept-Language header, and URL. So Astro doesn't seem to handle cookie based language selection with no URL param (which is ok but would deserve to be said explicitly)
the routing seems to rely on middlewares to be able to redirect users, yet doesn't seem to imply per-request SSR as user-land middleware do => it seems to have been mentioned above, but it feels like i18n routing is using an internal feature that could useful to other use cases.
can we set a generic [locale] parameter rather than explicit folders en, fr etc.?
my site is highly dynamic so I only have a big virtual [...path] route that handles all routes of the site. But I couldn't make i18n work with a page "en/[...path]" or "[locale]/[...path]", I hit 404 as soon as I setup I18n in Astro.config. Perhaps a mistake on my side, I'll try to craft a repro if possible
can we access Astro.preferredLocale without setting up i18n routing? This would allow to easily setup a client-side redirection, without having to explicitly read cookies and activate per-request rendering. Edit: actually this params weirds me out. Either you are doing per-request SSR and its a short cut for Accept-Language or explicit URL, or you are doing static rendering and it's equivalent to the current locale? Am I right?
Most of these may just be documentation issue but I am also unsure about the architecture itself. Astro made a quite opinionated choice here, with a solution quite similar how Next.js worked before version 12.
However since that, Next.js has started considering i18n routing as a part of the broader family of personnalization via redirection. User-land middlewares, which are meant to run also for static pages, allow devs to get full control of i18n.
My feeling is that this is the inevitable direction that all frameworks are meant to take at some point. In Astro, to implement i18n routing, you seem to use an internal feature allowing to have middleware that can run for each HTTP request but also preserve the static nature of the page. Making this feature available to end user would allow them to take full control over i18n instead of relying on the framework provided implementation, but also cover similar personalization use cases.
Edit: got answers to my questions, for now using an Edge Middleware is fine (so I can have a tiny redirection server in front of my Astro server) and discussion should keep going there: https://github.com/withastro/roadmap/discussions/795
Summary
i18n routing support baked into Astro.
Links