#Multilanguage json files in index.astro

1 messages · Page 1 of 1 (latest)

iron oxideBOT
#

Hi @earnest crown. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

To create a route for each language, you need to modify the getStaticPaths() function in your [slug].astro file to fetch the JSON files for each language from your CMS.

In your case, the JSON files are named as 'http://cms.baukasten.local/{language}/home.json'. You need to fetch these files for each language you support and generate the paths accordingly.

Here is how you can modify your [slug].astro file:

---
import { getGlobal } from '@lib/api.js';
import BaseLayout from '@layouts/BaseLayout.astro';
import Layouts from '@components/Layouts.astro';

export async function getStaticPaths() {
    const languages = ['en', 'fr', 'de']; // Add the languages you support
    const paths = [];

    for (const language of languages) {
        const response = await fetch(`<http://cms.baukasten.local/${language}/home.json`>);
        const data = await response.json();

        paths.push({
            params: {
                slug: data.language, // Assuming the language code is the slug
            },
        });
    }

    return paths;
}

const { slug } = Astro.params;
const response = await fetch(`<http://cms.baukasten.local/${slug}/home.json`>);
const data = await response.json();
const global = await getGlobal();
const pageTitle = global.siteTitle + ' | ' + data.title;
---

<BaseLayout pageTitle={pageTitle} data={data} global={global}>
    <Layouts layouts={data.layouts} data={data} global={global} />
</BaseLayout>

In this code, we are looping over an array of languages and fetching the corresponding JSON file for each language. We then push the language code (which we are using as the slug) and its corresponding data to the paths array. This will generate a page for each language.

Please note that you need to replace the languages array with the languages you support.

#

@earnest crown kapa.ai is still learning and improving, please let us know how it did by reacting below

earnest crown
#

@iron oxide i changed your code to my example, but its not working

---
import { getGlobal, getLanguages } from '@lib/api.js';
import BaseLayout from '@layouts/BaseLayout.astro';
import Layouts from '@components/Layouts.astro';
const API_URL = import.meta.env.KIRBY_URL;

export async function getStaticPaths() {
    const API_URL = import.meta.env.KIRBY_URL;
    const pages = await fetch(API_URL + '/index.json');
    const data = await pages.json();
    const languages = await getLanguages();
    const allLang = languages.map((lang) => lang.code);

    return data.map((item) => {
        return {
            params: {
                slug: item.uri,
            },
        };
    });
}

const { lang, slug } = Astro.params;
const pages = await fetch(API_URL + '/' + lang + '/' + slug + '.json');
const data = await pages.json();
const global = await getGlobal();
const pageTitle = global.siteTitle + ' | ' + data.title;
---

<BaseLayout pageTitle={pageTitle} data={data} global={global}>
    <Layouts layouts={data.layouts} data={data} global={global} />
</BaseLayout>
iron oxideBOT
#

Let me check the knowledge base for you. One moment! :books:

#

It seems like you're trying to generate paths for each language and page combination, but your getStaticPaths() function is currently only generating paths based on the page uri and not considering the languages.

You need to modify your getStaticPaths() function to generate paths for each language and page combination. Here's how you can do it:

---
import { getGlobal, getLanguages } from '@lib/api.js';
import BaseLayout from '@layouts/BaseLayout.astro';
import Layouts from '@components/Layouts.astro';
const API_URL = import.meta.env.KIRBY_URL;

export async function getStaticPaths() {
    const API_URL = import.meta.env.KIRBY_URL;
    const pagesResponse = await fetch(API_URL + '/index.json');
    const pages = await pagesResponse.json();
    const languages = await getLanguages();
    const allLang = languages.map((lang) => lang.code);

    const paths = [];

    for (const lang of allLang) {
        for (const page of pages) {
            paths.push({
                params: {
                    lang: lang,
                    slug: page.uri,
                },
            });
        }
    }

    return paths;
}

const { lang, slug } = Astro.params;
const pages = await fetch(API_URL + '/' + lang + '/' + slug + '.json');
const data = await pages.json();
const global = await getGlobal();
const pageTitle = global.siteTitle + ' | ' + data.title;
---

<BaseLayout pageTitle={pageTitle} data={data} global={global}>
    <Layouts layouts={data.layouts} data={data} global={global} />
</BaseLayout>

In this code, we are looping over all languages and pages, and generating a path for each combination. This will create a route for each language and page.

#

Please note that this assumes that your API returns a list of pages from API_URL + '/index.json' and a list of languages from getLanguages(). If this is not the case, you might need to adjust the code to match your API structure.

Sources:


Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@earnest crown kapa.ai is still learning and improving, please let us know how it did by reacting below

earnest crown
#

@iron oxide now i get the error: Unexpected token 'N', "Not found" is not valid JSON

iron oxideBOT
#

Let me check the knowledge base for you. One moment! :books:

#

The error message "Unexpected token 'N', 'Not found' is not valid JSON" typically occurs when a fetch request is made to a URL that does not return a valid JSON response. In your case, it seems like the request to fetch the page data is returning a "Not found" response, which is not valid JSON.

This could be due to a number of reasons:

  1. The URL you're trying to fetch does not exist. Make sure that the URL is correct and that the server is properly configured to return a JSON response for that URL.

  2. The server is not properly configured to handle the request method (GET, POST, etc.) you're using.

  3. There's a network issue that's preventing the fetch request from reaching the server.

To debug this issue, you can add a console.log statement before the fetch request to log the URL you're trying to fetch. Then, you can manually visit that URL in your browser or use a tool like Postman to see what response you get.

Here's how you can modify your code to log the URL:

const {{ lang, slug }} = Astro.params;
const url = API_URL + '/' + lang + '/' + slug + '.json';
console.log('Fetching URL:', url);
const pages = await fetch(url);
const data = await pages.json();

If the URL is correct and you're still getting a "Not found" response, you might need to check your server configuration or consult with your backend team or CMS provider.

#

Sources:


Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@earnest crown kapa.ai is still learning and improving, please let us know how it did by reacting below

earnest crown
#

@iron oxide i found the problem - lang doesnt work as astro.params. but how can i generate a astro file for all language and slug files? This is my code:

---
import { getGlobal, getLanguages } from '@lib/api.js';
import BaseLayout from '@layouts/BaseLayout.astro';
import Layouts from '@components/Layouts.astro';
const API_URL = import.meta.env.KIRBY_URL;

export async function getStaticPaths() {
    const API_URL = import.meta.env.KIRBY_URL;
    const pagesResponse = await fetch(API_URL + '/index.json');
    const pages = await pagesResponse.json();
    const languages = await getLanguages();
    const allLang = languages.map((lang) => lang.code);
    const paths = [];

    for (const lang of allLang) {
        for (const page of pages) {
            paths.push({
                params: {
                    lang: lang,
                    slug: page.uri,
                },
            });
        }
    }
    return paths;
}

const { slug } = Astro.params;
const pages = await fetch(API_URL + '/' + slug + '.json');
const data = await pages.json();
const global = await getGlobal();
const pageTitle = global.siteTitle + ' | ' + data.title;
---

<BaseLayout pageTitle={pageTitle} data={data} global={global}>
    <Layouts layouts={data.layouts} data={data} global={global} />
</BaseLayout>
iron oxideBOT
#

Let me check the knowledge base for you. One moment! :books:

#

The issue you're facing is that you're trying to access lang from Astro.params but it's not available because you're not using it in your file path.

In Astro, the file path determines the parameters you can access. For example, if you have a file named [lang]/[slug].astro, you can access lang and slug from Astro.params.

To generate a file for all language and slug combinations, you need to structure your files and folders to match this pattern. Here's how you can do it:

  1. Create a folder for each language in your src/pages directory. For example, if you support English and French, you would have src/pages/en and src/pages/fr.

  2. Inside each language folder, create a [slug].astro file. This file will be used to generate the pages for that language.

  3. In each [slug].astro file, you can access the language from the folder name and the slug from the file name using Astro.params.

Here's how your [slug].astro file would look like:

---
import { getGlobal } from '@lib/api.js';
import BaseLayout from '@layouts/BaseLayout.astro';
import Layouts from '@components/Layouts.astro';
const API_URL = import.meta.env.KIRBY_URL;

export async function getStaticPaths() {
    const API_URL = import.meta.env.KIRBY_URL;
    const pagesResponse = await fetch(API_URL + '/index.json');
    const pages = await pagesResponse.json();
    const paths = [];

    for (const page of pages) {
        paths.push({
            params: {
                slug: page.uri,
            },
        });
    }

    return paths;
}

const { lang, slug } = Astro.params;
const pages = await fetch(API_URL + '/' + lang + '/' + slug + '.json');
const data = await pages.json();
const global = await getGlobal();
const pageTitle = global.siteTitle + ' | ' + data.title;
---
#

<BaseLayout pageTitle={pageTitle} data={data} global={global}>
<Layouts layouts={data.layouts} data={data} global={global} />
</BaseLayout>


In this code, `lang` is the language folder name and `slug` is the page slug. We're fetching the page data for the specific language and slug from the API and rendering it using the `BaseLayout` and `Layouts` components.

Please note that this assumes that your API returns a list of pages for each language from `API_URL + '/' + lang + '/index.json'`. If this is not the case, you might need to adjust the code to match your API structure.

Sources:
- **Astro Documentation: Dynamic Routes** (<https://docs.astro.build/en/core-concepts/routing/#dynamic-routes>)
- **Astro Documentation: Making a blog with Astro and Storyblok** (<https://docs.astro.build/en/guides/cms/storyblok/>)
- **Astro Blog: Astro 0.19** (<https://astro.build/blog/astro-019/>)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
#

@earnest crown kapa.ai is still learning and improving, please let us know how it did by reacting below

earnest crown
#

@iron oxide Ok. Thanks for making this clear. I seems like i cant work with the lang as astro.params. can you modify the code to combine the slug an lang value? here is my current code:

---
import { getGlobal, getLanguages } from '@lib/api.js';
import BaseLayout from '@layouts/BaseLayout.astro';
import Layouts from '@components/Layouts.astro';
const API_URL = import.meta.env.KIRBY_URL;

export async function getStaticPaths() {
    const API_URL = import.meta.env.KIRBY_URL;
    const pagesResponse = await fetch(API_URL + '/index.json');
    const pages = await pagesResponse.json();
    const languages = await getLanguages();
    const allLang = languages.map((lang) => lang.code);
    const paths = [];

    for (const lang of allLang) {
        for (const page of pages) {
            paths.push({
                params: {
                    lang: lang,
                    slug: page.uri,
                },
            });
        }
    }
    return paths;
}

const { slug } = Astro.params;
const pages = await fetch(API_URL + '/' + slug + '.json');
const data = await pages.json();
const global = await getGlobal();
const pageTitle = global.siteTitle + ' | ' + data.title;
---

<BaseLayout pageTitle={pageTitle} data={data} global={global}>
    <Layouts layouts={data.layouts} data={data} global={global} />
</BaseLayout>
iron oxideBOT
#

Let me check the knowledge base for you. One moment! :books:

#

If you want to combine the lang and slug into a single parameter, you can modify your getStaticPaths() function to concatenate the lang and slug with a separator (like a dash - or underscore _). Then, in your fetch request, you can split this combined parameter back into lang and slug.

Here's how you can modify your code:

---
import { getGlobal, getLanguages } from '@lib/api.js';
import BaseLayout from '@layouts/BaseLayout.astro';
import Layouts from '@components/Layouts.astro';
const API_URL = import.meta.env.KIRBY_URL;

export async function getStaticPaths() {
    const API_URL = import.meta.env.KIRBY_URL;
    const pagesResponse = await fetch(API_URL + '/index.json');
    const pages = await pagesResponse.json();
    const languages = await getLanguages();
    const allLang = languages.map((lang) => lang.code);
    const paths = [];

    for (const lang of allLang) {
        for (const page of pages) {
            paths.push({
                params: {
                    slug: `${lang}-${page.uri}`, // Combine lang and slug with a dash
                },
            });
        }
    }
    return paths;
}

const { slug } = Astro.params;
const [lang, pageSlug] = slug.split('-'); // Split the combined slug back into lang and slug
const pages = await fetch(`${API_URL}/${lang}/${pageSlug}.json`);
const data = await pages.json();
const global = await getGlobal();
const pageTitle = `${global.siteTitle} | ${data.title}`;
---

<BaseLayout pageTitle={pageTitle} data={data} global={global}>
    <Layouts layouts={data.layouts} data={data} global={global} />
</BaseLayout>

In this code, we're combining lang and slug into a single parameter with a dash - as the separator. Then, when we need to fetch the page data, we split this combined parameter back into lang and slug using the split() method.

#

@earnest crown kapa.ai is still learning and improving, please let us know how it did by reacting below

earnest crown
#

@iron oxide can you change the seperator to '/'?

iron oxideBOT
#

Let me check the knowledge base for you. One moment! :books: