withastro / docs

Astro documentation
https://docs.astro.build/
MIT License
1.3k stars 1.46k forks source link

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

Open aureliendossantos opened 1 month ago

aureliendossantos commented 1 month ago

📚 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

sarah11918 commented 2 weeks ago

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 commented 4 days ago

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 commented 3 days ago

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:

Meanwhile, with:

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

We can have:

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 commented 2 days ago

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 commented 1 day ago

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.