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@2.4.4 broke collection content translation #34

Closed narduin closed 1 year ago

narduin commented 1 year ago

Hi!

Updating to astro@2.4.4 broke my collection translation logic, I could not find a workaround yet. I suspect it has to do with this PR but I can't be certain…

Right now I have a content collection called 'articles' with two subfolders (en and fr). Inside src/pages/articles/[slug].astro, I'm using the following logic to get the translated articles:

import { astroI18n } from "astro-i18n";
astroI18n.init(Astro); // does not change anything if present or not

export async function getStaticPaths() {
    const articles = await getCollection("articles", ({ data }) => {
        // I have a frontmatter property called lang in each article.
        // I tried using the id filter as seen in the astro docs but no luck either.
        return data.lang === astroI18n.langCode;
    });
    return articles.map((article) => ({
        params: { slug: article.slug },
        props: { article },
    }));
}

What happens is the frontmatter translates correctly but the acutal content does not. When building the website, the same version of the content will be displayed on both languages instead of its translation.

Reverting back to astro@2.4.3 resolves everything 😅 I tested with astro-i18n v1.7.0 and v1.6.1 and astro@2.4.5 as well. I have a branch available for reproduction.

Alexandre-Fernandez commented 1 year ago

You should be able to use extractRouteLangCode(import.meta.url) to retrieve the lang code in v1.7.1 (https://github.com/Alexandre-Fernandez/astro-i18n#extractroutelangcode). I think this happens because getStaticPaths runs before astroI18n.init(Astro). This probably wouldn't be a problem if astro had a way for integrations to initialize state using the global Astro. Unfortunately as far as I know that's not the case and it has to be done manually in the frontmatter.

narduin commented 1 year ago

Thanks a lot for the quick fix! I was not able to implement it however… Could you provide an example using extractRouteLangCode(import.meta.url)?

I tried the following:

export async function getStaticPaths() {
    const articles = await getCollection("articles", ({ data }) => {
        return data.lang === extractRouteLangCode(import.meta.url);
    });
    return articles.map((article) => ({
        params: { slug: article.slug },
        props: { article },
    }));
}

Logging extractRouteLangCode(import.meta.url) still only return 1 locale, I think I'm not doing this correctly. I updated the reproduction branch.

Alexandre-Fernandez commented 1 year ago

My bad, it was an oversight. I know how I can fix it however but the problem is the API might be non consistent and I don't like that, trying to find a better solution. EDIT: Ok I have an idea that should work.

Alexandre-Fernandez commented 1 year ago

This time it should be fixed for real, here's how to do it : https://github.com/Alexandre-Fernandez/astro-i18n#createstaticpaths

narduin commented 1 year ago

Thanks again! I'm really sorry but I'm getting an error when importing createStaticPaths, am I not supposed to?

import { astroI18n, createStaticPaths } from "astro-i18n";
// Module '"astro-i18n"' has no exported member 'createStaticPaths'.ts(2305)

I tried to look at your source code to avoid bothering you but I don't understand typescript really well, sorry.

Alexandre-Fernandez commented 1 year ago

@narduin I just tried it in a new project and I don't have your error. image Try deleting node_modules and reinstalling, make sure it's v1.7.2. If it doesn't work try the same but also delete the .lock file. EDIT: you also probably want to rerun i18n:sync

narduin commented 1 year ago

It's working, I needed to restart vscode. Now I just have to make this work with getCollection!

narduin commented 1 year ago

Well, the markdown content is still broken but I think it might be astro's fault. When I log the article content, the correct translated version is shown. However, the content on the actual web page, is not. It feels like there might be a problem with the rendered content from the render function const { Content } = await article.render();

I'll open an issue on the astro repo.

Alexandre-Fernandez commented 1 year ago

weird, do you have a branch where I can test that on, I'm curious, maybe I can find a solution

narduin commented 1 year ago

I've updated the reproduction branch where I implemented your fix here.

Alexandre-Fernandez commented 1 year ago

That's weird it looks like it works just fine for me.

astro 2.5.0
astro-i18n 1.7.2

image image All I did is git clone, git checkout bug/2.4.4 and pnpm install.

narduin commented 1 year ago

Yes the frontmatter and i18n translations are working fine but not the markdown rendered content of the articles. You can see that from the titles in the table of content from your screenshots. The second ones should be in french.

EDIT: It's really weird. It seems only the content from the render function is bugging. When using {article.body}, the content updates with the correct translation (although it's raw markdown).

Alexandre-Fernandez commented 1 year ago

That's weird, it looks like a problem at the astro level indeed because when logging the article it is translated. As a workaround you can use this regex /(#+) (?: +)?([^\n]+)(?: +)?\n/g and RegExp.exec to fetch the headings from the article body property (the 1st group is the heading level and the 2nd group is the actual text). As for the content, you can use const content = await Astro.__renderMarkdown(article.body) to retrieve it as a workaround. It's an internal function to render MD. I think I'm gonna add a builtin render function until they fix this. Please make sure you make an issue about this on their repo so they look into it. Otherwise they may delete __renderMarkdown and then we're f ed.

Alexandre-Fernandez commented 1 year ago

I made a builtin replacement https://github.com/Alexandre-Fernandez/astro-i18n#rendercontent.