#Get json from a headless CMS only once at build

7 messages · Page 1 of 1 (latest)

stray spear
#

I am using a headless CMS and getting the data like below.

---
const res = await fetch(`${url}?${query}`, {
    headers: headers,
});

const json = await res.json();
---

This works fine, but I'd like to have this data in multiple pages and I don't want to fetch each time due to the headless CMS access count.

I've come up with an idea to make an endpoint so that the pages that need the API data can get it "after" the build. But I believe that is kind of ruining the pros of Astro/SSG.

Is there any way to get the fetched data at build time for multiple pages only once?

shy glacierBOT
#
Still waiting for an answer?

It looks like no-one has responded to your question yet. People might not be available right now or don’t know how to answer your question. Want an answer while you wait? Try asking our experimental bot in #1095492539085230272.

gleaming plank
#

I had a similar goal and I did it using Astro's nano stores. These can't be used in Astro components though, so you would need to create e.g. React components to share the state between and then import those into your Astro pages. Might be a better way using only Astro, but I'm not sure.

cyan hollow
#

You can create an js or ts file specifically for fetching the data then import what you need to each page... ?

stray spear
#

@gleaming plank
Thank you for answering.
I've tried nano stores (with persistent plugin) for shopping cart. For me it was so confusing since I'm not really used to other components such as React, svelte, etc.
But thank you for suggesting, I'll try it again!

stray spear
#

@cyan hollow
Thank you for answering.
This way ( https://docs.astro.build/en/core-concepts/endpoints/ ), I could get the data after the build using client side fetch.
Can I get the fetched data during the build?

My .ts file (/src/pages/api.json.ts) is something like this.

export async function get({ params, request }) {

    ~~~

    const res = await fetch(`${url}?${query}`, {
        headers: headers,
    });

    const json = await res.json();

    return {
        body: JSON.stringify(json),
    };
}
Astro Documentation

Learn how to create endpoints that serve any kind of data

harsh dagger
#

Why not just do the fetch in one file and import it multiple places?

// data.ts
export const data = (await fetch('cms-url')).then((res) => res.json());

Then in your astro files you can import and use it and it’ll only make the request once.