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

Internationalization (i18n) guide and recipe should be merged #9256

Open
aureliendossantos opened this issue Aug 29, 2024 · 10 comments
Open
Labels
help wanted Issues looking for someone to run with them! improve documentation Enhance existing documentation (e.g. add an example, improve description)

Comments

@aureliendossantos
Copy link
Contributor

📚 Subject area/topic

Internationalization (i18n)

📋 Page(s) affected (or suggested, for new content)

https://docs.astro.build/en/guides/internationalization/
https://docs.astro.build/en/recipes/i18n/

📋 Description of content that is out-of-date or incorrect

The guide Internationalization (i18n) Routing lacks several tips that would make the Astro feature more attractive. Personally, I had given up on using Astro's i18n until I realised the following points, which made my experience so much better:

  1. Every example block shows a directory structure with a folder per locale, in which you have to duplicate every .astro file:

    image

    It seems inconvenient and off-putting, I can't imagine a case where I'd like to do this. The docs suggests in the text that you could create a /[locale]/ folder, but I must admit that when skimming through the page, I missed it and only saw the several examples like in the screenshot. I think a more proeminent example block with /[locale] and/or /[...locale] (see 2.) would better showcase the flexibility of the feature.

  2. An info is missing from the guide and the alternative recipe (Add i18n features): What do you do when you have a defaultLocale without a prefix like /en/? (It's the default behaviour in the new feature) The answer is simple: you use /[...locale] and handle the undefined value in getStaticPaths. Pretty simple, but if an Astro beginner isn't aware of this possibility, the guide and the recipe appear to be missing critical info. Here's an example of what should be done:

    // Store this in a utils file
    export const langParams = [undefined, "fr"]
    // In every [...lang]/*.astro file
    export function getStaticPaths() {
    	return langParams.map((lang) => ({
    		params: { lang: lang },
    	}))
    }
  3. By itself, the guide about the Astro feature does not give enough examples to get you started. You have to use /[...locale] and adapt the following tips from the recipe Add i18n features to have a working website:

    • The clever functions in Translate UI strings (you can use them with the new Astro feature like so: useTranslations(Astro.currentLocale)),
    • The LanguagePicker example is nice to have, because in Static mode, I don't think there is any other way to switch languages or to detect the client's preferred locale.

    The Astro feature is very flexible, so I don't see why people would want to not use it. That's why I feel like the recipe page is "legacy" and could be merged into the new guide for easier access to these clever tips.

🖥️ Reproduction in StackBlitz (if reporting incorrect content or code samples)

No response

@aureliendossantos aureliendossantos added the improve documentation Enhance existing documentation (e.g. add an example, improve description) label Aug 29, 2024
@sarah11918
Copy link
Member

Thank you for this amazingly detailed feedback, @aureliendossantos !

We have a bit of a legacy problem here, and I do have updating i18n API docs on my plate, and probably including better linking to and discovery of that guide.

So the backstory is:

This recipe was written well before we had the i18n Routing API. It's based on how we created our i18n system for Astro Docs, and then Starlight, both of which are older than our i18n Routing API. (And which have been updated to take a little from, but still do not yet fully use this API for routing)

So, the guide is a bit more complete about setting up an i18n site as a whole, because that's what we did! And the i18n Routing guide contains information about only the routing part of it (ignoring any "extra features" like translating UI strings because it's not specific to routing, but it is a huge part of Astro Docs/Starlight implementations).

So the current situation is:

The two don't perfectly align! And as you've correctly identified, we don't right now have a unified "here's how to set up a site" story. Add to the mix that our experimental Content Layer API is dropping in the 5.0 beta NEXT WEEK, which will probably open up to even more content management options (like pulling in your translations from external sources), and we certainly don't have a full i8n story around that yet to tell!

All this is to say that this would be an amazing addition to our current docs that we don't currently provide in an all-in-one format. I would certainly be open to anyone wanting to help contribute to that! It's on our wishlist, but not our immediate plate with lots of new docs currently written to support the new features in and upgrading to v5.

BUT, this post will be a super helpful kick off for that, so I hope people see this, continue to leave feedback about what will be helpful, and maybe propose some contributions!

@sarah11918 sarah11918 added the help wanted Issues looking for someone to run with them! label Sep 9, 2024
@sarah11918
Copy link
Member

Just bumping this for freshness in case anyone would like to "freshen up" our i18n guide that pre-dates our i18n routing API features!

@ArmandPhilippot
Copy link
Contributor

I agree the recipe could be merged with the guide because many expect to find this kind of information there (translating UI strings or routes). However, I see two caveats:

  1. There is no official user guide and the implementation depends on each person's needs. In my opinion the recipe works very well for small sites with some adjustments if necessary; Starlight on its side now uses i18next with a function provided through a middleware. Others might have other methods that work well with their project.
  2. Recommending the use of [locale] (or [...locale]) rather than creating folders for each locale doesn't seem ideal to me. Again, it will depend on the project I think.

It seems inconvenient and off-putting, I can't imagine a case where I'd like to do this.

Translate the slug?

With:

/src/pages
└── [locale]/
    ├── about.astro
    └── contact.astro

Considering that the site is available with the en, es and fr locales, this will generate:

  • /en/about
  • /es/about
  • /fr/about

Meanwhile, with:

/src/pages
├── es/
│   ├── sobre-nosotros.astro
│   └── contacto.astro
├── fr/
│   ├── a-propos.astro
│   └── contact.astro
├── about.astro
└── contact.astro

We can have:

  • /en/about
  • /es/sobre-nosotros
  • /fr/a-propos

From both a user and SEO perspective, it's better.

Perhaps the file names in the example should be translated to make it more meaningful.

My example can probably be rewritten using getStaticPaths with the following structure:

/src/pages
└── [...locale]/
    └── [...slug].astro

But it might be more complicated to explain to newcomers... especially without knowing where their content comes from and if they want different page templates.

@sarah11918
Copy link
Member

To be clear, I think if there's any improvement/solution to be had here, it's in refreshing the recipe and NOT moving the content into the guide page, for similar reasons: a recipe is an opinionated suggestion of a "base dish".

Also, the Internationalization page is about using the API which is a routing API only and should stay focused on the connection between creating/validating route path not actual translation. (Which again, will be very much up to an individual project.)

The current recipe as it exists works, and I think the question is, can it be made more helpful by acknowledging the existence of the newer routing API? The answer might be "no", but that is the question to be asking here, and the way we will evaluate potential improvements!

@sasoria
Copy link
Contributor

sasoria commented Sep 27, 2024

I think the recipe could be simplified somewhat, at least the getLangFromUrl() function can be replaced by Astro.currentLocale. I've had positive feedback from this example I made to help others, though I do understand that [locale] is not for everyone.

@sarah11918
Copy link
Member

Thanks @sasoria ! Would you be willing to make a PR to the recipe, or help guide us through exactly what's different about your example? It certainly does make sense that if we can incorporate Astro.currentLocale from the i18n routing API, especially if it simplifies the process, then we should! This would help unify the two separate pages.

@sasoria
Copy link
Contributor

sasoria commented Oct 7, 2024

Sure, I could try to make a PR this week!

@sarah11918
Copy link
Member

Thank you, @sasoria ! I know this is one inconsistency (between these two pages) that often gets mentioned!

@sarah11918
Copy link
Member

@sasoria Are you still interested in updating the i18n recipe with Astro's i18n features like Astro.currentLocale?

In general, we will otherwise keep the recipe as is but just update to use the new i18n features!

@Fryuni
Copy link
Member

Fryuni commented Dec 19, 2024

Just a small little detail about routing on this example:

/src/pages
└── [...locale]/
    └── [...slug].astro

That would not work as expected in on-demand pages (SSR). Rest parameters ([...name]) can match any number of path segments and as a consequence using two rest parameters in the same routes makes parsing the path ambiguous. For example, a request to /en/blog/amazing-article could be parsed in any of the following ways:

  • {locale: undefined, slug: 'en/blog/amazing-article'}
  • {locale: 'en', slug: 'blog/amazing-article'}
  • {locale: 'en/blog', slug: 'amazing-article'}
  • {locale: 'en/blog/amazing-article', slug: undefined}

It can be used to generate the page, so for prerendered pages, this is fine since the routes are generated from getStaticPaths. Astro provides no guarantees about which of those interpretations will be used during parsing. We use a library to turn the file path into a parsing function, which also doesn't guarantee the behavior when facing this ambiguity (in fact, the behavior changed during a patch release earlier this year).

So if you do want to have an optional locale in the URL and use SSR the recommendation would be to have the entire tree twice, once on src/pages and once on src/pages/[locale]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Issues looking for someone to run with them! improve documentation Enhance existing documentation (e.g. add an example, improve description)
Projects
None yet
Development

No branches or pull requests

5 participants