Next.js Discord

Discord Forum

Page that fetches from an API becomes static and doesn't fetch data from API after building it

Answered
Basset Bleu de Gascogne posted this in #help-forum
Open in Discord
Basset Bleu de GascogneOP
Hi, I'm building a blog that fetches from a local Directus API. I have a file /app/blog/page.tsx. I am fetching from an API at the beginning to get all the blogs. I have a problem though, it doesn't fetch when the app is built. My /blog/[id]/page.tsx works perfectly fine though. API keys are perfectly fine. Everything works during dev. I think the problem is that the /app/blog/page.tsx gets built as static for some reason.

I found that the fix is to add export const dynamic = "force-dynamic"; to /app/blog/page.tsx, but that doesn't seem too smart? Is there a better way to do this? Thanks!
Answered by Arinji
Export dynamic to be true is the best method here, nextjs can't understand that you have no store in the sdk you are using, it sees you don't look for dynamic functions like cookies and headers so it think you only fetch it once. You can also use unstable no store in the function but it's unstable so
View full answer

6 Replies

Basset Bleu de GascogneOP
And here's my code. I'm using the app router and NextJS 14.2.5.

/app/blog/page.tsx:
import Link from "next/link";
import { FaAnglesRight } from "react-icons/fa6";

import { DateToLocal } from "@/components/ui/DateToLocal";
import { Blog } from "@/types";
import { fetchBlogs } from "@/services/BlogRequests";

export default async function Home() {
    const blogs: Blog[] = await fetchBlogs();

    return (
        <main className=""><p>code here</p>
        </main>
    );
}


BlogRequests.ts:
import { createDirectus, rest, readItem, authentication, readUser, readItems } from "@directus/sdk";
import { Blog, User } from "@/types";

// create a Directus client to connect to the Directus API
const client = createDirectus(process.env.DIRECTUS_URL as string)
    .with(rest({ onRequest: (options) => ({ ...options, cache: "no-store" }) }))
    .with(authentication());

export const fetchBlogs = async () => {
    try {
        await client.setToken(process.env.DIRECTUS_KEY as string);
        const res = (await client.request(readItems("blog"))) as Blog[];
        return res;
    } catch (error) {
        console.error("Error while fetching blogs", error);
        return [];
    }
};

export const fetchBlogById = async (id: string) => {
    try {
        if (!id) return null;
        await client.setToken(process.env.DIRECTUS_KEY as string);
        const result = (await client.request(readItem("blog", id))) as Blog;
        return result;
    } catch (error) {
        console.error("Error while fetching blog", error);
        return null;
    }
};
Export dynamic to be true is the best method here, nextjs can't understand that you have no store in the sdk you are using, it sees you don't look for dynamic functions like cookies and headers so it think you only fetch it once. You can also use unstable no store in the function but it's unstable so
Answer
@Basset Bleu de Gascogne
the preferred method in the future is unstable_noStore: https://nextjs.org/docs/app/api-reference/functions/unstable_noStore

but at the moment since it is still unstable_, export const revalidate = 0 or export const dynamic = 'force-dynamic' are the ways to tell nextjs that i want this page to be dynamic.
Basset Bleu de GascogneOP
Thank you! @Arinji @joulev