Next.js Discord

Discord Forum

output: “export” not generating index.html on out/ when using cache: ‘no-store’ on fetch API

Unanswered
Mini Satin posted this in #help-forum
Open in Discord
Avatar
Mini SatinOP
For some reason when adding cache: ‘no-store’ on a fetch API it does not generate this page on out/ folder, if I remove this line it generates ok (but with cache)

24 Replies

Avatar
Mini SatinOP
Here is the 'pnpm build' output at the end
Image
And this is one of my components

import Image from "next/image";
import Link from "next/link";
import type { NavbarItems } from "@/types";

export async function Navbar() {
  const response = await fetch(
    `${process.env.NEXT_PUBLIC_API_URL}/navbar_items`,
    {
      method: "GET",
      headers: {
        "User-Agent": "*",
        Accept: "application/json; charset=UTF-8",
      },
      cache: "no-store",
    },
  );
  const data: NavbarItems = await response?.json();
  console.log(data);
  const navItems = data?.data ?? [];

  return (
    <header className="h-navbar fixed top-0 left-0 right-0 z-[999] bg-white shadow px-[1.25rem] py-[0.625rem] flex items-center justify-between">
      <Image
        alt=""
        src="/assets/logo-black.svg"
        width={0}
        height={0}
        className="w-auto h-auto"
      />

      <div className="flex item-center gap-[2.5rem] text-azul">
        <nav className="hidden lg:flex">
          <ul className="flex items-center gap-[1.25rem]">
            {navItems.map((link) => {
              return (
                <li key={link.id} className="text-[0.875rem] font-semibold">
                  <Link href={link.href}>{link.title}</Link>
                </li>
              );
            })}
          </ul>
        </nav>

        <button className="block relative hamburguer lg:hidden focus:outline-none">
          <Image
            alt=""
            src="/assets/burguer.svg"
            width={0}
            height={0}
            className="w-auto h-auto"
          />
        </button>

        <button className="flex items-center gap-[0.4rem]">
          <span className="font-semibold text-[0.875rem]">PT</span>
          <Image
            alt=""
            src="/assets/globe.svg"
            width={0}
            height={0}
            className="w-auto h-auto"
          />
        </button>
      </div>
    </header>
  );
}
If I remove the cache from the fetch API like this. It generates the index.html on out/

const response = await fetch(
    `${process.env.NEXT_PUBLIC_API_URL}/navbar_items`,
    {
      method: "GET",
      headers: {
        "User-Agent": "*",
        Accept: "application/json; charset=UTF-8",
      },
     
    },
  );
Avatar
Shy Albatross
of course, you're telling it that the fetch that the component awaits on - therefore the component itself - must be dynamic, so it will generate this page as a lambda, not as static HTML
Avatar
Mini SatinOP
I am recording it one second
How can I not cache then?
Avatar
Shy Albatross
you want it static but you also want it to be dynamic, so which way do you want it?
Avatar
Mini SatinOP
I have an CMS where I can trigger new builds, but the cache stays
I want it to get the latest data on each build
Avatar
Shy Albatross
the use ISR and revalidatePath that you trigger via an API endpoint from your CMS
or revalidateTag, whichever suits your use case better, and tag the fetch
Avatar
Mini SatinOP
Can you point me any doc about it or show any example?
Avatar
Shy Albatross
your fetch on this page isn't parametrized so revalidatePath would be the winner
you can expose an API route (make it secure somehow, of course), that route handler would call revalidatePath
then you can send a request to that API endpoint from your CMS
Avatar
Mini SatinOP
Ok I think I got it
Thanks about it!
Avatar
Mini SatinOP
@Shy Albatross , for what I undertood, I should create a Route Handler like this

import { revalidatePath } from "next/cache";

export async function GET() {

  revalidatePath("/", "layout");
  return Response.json({ revalidated: true, now: Date.now() });
}


and call this endpoint before triggering a new build, right?
But I also need to be alerted about this, I don't think It would work right away
Image
Avatar
Shy Albatross
it would work on next request, yes, so next time this page is requested (or built, I suppose?)
I'd make that handler a POST, because 1) it modifies stuff 2) it won't get cached then
Avatar
Mini SatinOP
I fixed it in the stupidest way possible, by making a "new request url" each time it is called by adding a new parameter called timestamp

  const response = await fetch(
    `${
      process.env.NEXT_PUBLIC_API_URL
    }/navbar_items?sortBy=order&active=1&limit=7&timestamp=${Date.now()}`,
    {
      headers: {
        "User-Agent": "*",
        Accept: "application/json; charset=UTF-8",
      },
    },
  );
Avatar
Shy Albatross
well, kinda brute force, but if it works it ain't stupid