Alexandre-Fernandez / astro-i18n

A TypeScript-first internationalization library for Astro.
https://www.npmjs.com/package/astro-i18n
MIT License
249 stars 10 forks source link

astro@1.7.0 breaks i18n #9

Closed narduin closed 1 year ago

narduin commented 1 year ago

Hey @Alexandre-Fernandez,

it seems that when upgrading to astro@1.7.0 and later (1.7.2 tested) this bug behaviour comes back. I upgraded both packages of this demo repo and none of the locales is correctly displaying…

It works up until astro@1.6.15, no idea what changed there sorry.

Alexandre-Fernandez commented 1 year ago

You are using astroI18n.langCode in the page's frontmatter, here. Check my explanation here. I'll reopen the issue if you still have the problem after fixing this (please update the repo with the fixes if you do). Also I advise you to have I18nProvider wrap the whole app, including the html tags.

narduin commented 1 year ago

Thank you for the explaination. I'm afraid I'm lost as to where I'm supposed to use I18nProvider.

Until now I've used it inside a layout. I was not including the html because it would mess up the rendering (html attributes are stripped). I tried wrapping my whole html but nothing changed. I tried putting my html inside another layout and wrapping that layout with the provider but it didn't work.

I've removed astroI18n from the frontmatter (except in the lnguage switcher) but it breaks anyway. I've updated the repo.

Alexandre-Fernandez commented 1 year ago

Indeed the last version of astro changes the order of execution, the wrapper component used to run first, now the page runs first :

  1. pages runs with outdated langCode
  2. provider updates the langCode to the correct value
  3. components wrapped by the provider run with the correct langCode

So as long as you don't use astroI18n.langCode at all in the page you should be fine (for example everything should work fine inside your LangSwitcher component), but that's a pretty big problem.

I have a solution but that would involve generating an exact copy of every page for every translation with only one line changing (astroI18n.langCode = "currentLang") at the top of the frontmatter. That would be pretty bad, I'm thinking of an alternative solution, for some reason astro doesn't have a way to have an init code run before everything.

EDIT: The best solution I found at the moment is to make a function that replaces I18nProvider that you would have to run in every page at the top of the frontmatter, I'm looking for a better one but it's not looking good...

Alexandre-Fernandez commented 1 year ago

10 fixes this and adds some other minor improvements...

I deleted I18nProvider and replaced it by a method of astroI18n called init. Use astroI18n.init(Astro) at the top of each page and everything should be fixed. Once astroI18n.init runs it will guarantee that astroI18n.langCode is up to date.

It's not the best DX to have to put this in every page, but Astro gives me no other choice, than this or modifying the page generation, as explained before. Looking forward for a better solution from the astro devs.

narduin commented 1 year ago

Wow thanks, this works great! 💯 It's making astroI18n.langCode available in the frontmatter, which is so useful!

I think the doc might be wrong though because it says to import astroI18n from astro-i18n/components which does not exist apparently. I imported without components and it's all good though:

import { astroI18n } from "astro-i18n"

Alexandre-Fernandez commented 1 year ago

Wow thanks, this works great! 100 It's making astroI18n.langCode available in the frontmatter, which is so useful!

I think the doc might be wrong though because it says to import astroI18n from astro-i18n/components which does not exist apparently. I imported without components and it's all good though:

import { astroI18n } from "astro-i18n"

yeah sorry it's a typo I'll fix it later