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

Translate in .ts file -> Cannot perform operation, astro-i18n is not initialized. #68

Open Nkay opened 11 months ago

Nkay commented 11 months ago

Describe the bug I cannot load a translation from a .ts file - something the previous i18n implementation allowed. Do I have to change this behaviour? Suggestions on how to do it?

I tried to find the minimum attack surface for my project - it is attached.

To Reproduce Steps to reproduce the behavior:

  1. Clone Repo
  2. Start Astro
  3. Visit Page

Expected behavior It should work ;)

Mandatory reproduction repository https://github.com/Nkay/i18n-bug-reproduce-2

Alexandre-Fernandez commented 11 months ago

your repo is private

Nkay commented 11 months ago

oh yes, sorry - corrected.

Alexandre-Fernandez commented 11 months ago

This is happening because the typescript files runs before the middleware. But even if the translations were loaded you would still have a problem because the current route is set in the middleware. Without the information on the current route you could not access page translations. When using astroI18n outside a template wrap it in a getter, you can retrieve the value once it's properly intialized :

// old
t("my_key")
// new
() => ("my_key")

I will try to document this and add methods to be able to initialize astroI18n outside the middleware. I'll leave this open until then.

Alexandre-Fernandez commented 11 months ago

I investigated a bit, the TS modules run before everything because of vite which apparently initializes every module before the file that imports it runs. This is really annoying, I also want astro-i18n to be used seamlessly in TS modules but this will need some rework to the core functionality. Thanks for pointing out this issue, I'm thinking about a good way of solving it. For the moment you can wrap the calls inside getters (delaying the actual call until the middleware has run).

Nkay commented 11 months ago

Hi Alexandre,

I changed the occurences (they were mostly in a link element, in the nav and the footer) and so it was only about an hour of work to change it from link.asd -> t(link.asd), and now it fully works again. Thanks for taking the time and having a look into it!

perinazzoo commented 11 months ago

I have a related problem here, the only difference is that we are using server side render as default output, any updates here @Alexandre-Fernandez ? Can you provide a workaround until you give us a permanent solution?

Alexandre-Fernandez commented 11 months ago

@perinazzoo If you are using the translations in the template the workaround is using getters instead. Otherwise as of now there is no workaround, as explained before, even if the translations were loaded you wouldn't be able to access the current route's translations because astro-i18n cannot detect it since Astro loads all modules before the request comes in.

This is not a simple fix, first I have to make sure that the library is initialized before the module runs, then I need to add a way to fetch a translation from any group/page (since the current route will be unknown in the module) and I will probably also need to make every call to the t function return a getter instead. I didn't have time to think about the exact implementation but it would probably be something along those lines.

This issue is on my priority list for sure and I will fix it as soon as I can, however I'm very busy at the moment and I can't afford to work on this, if this is a deal-breaker I'm sorry but I can't help you at the moment.