Next.js Discord

Discord Forum

Multiple revalidateTag() fails silently

Unanswered
Jersey Wooly posted this in #help-forum
Open in Discord
Avatar
Jersey WoolyOP
Callig multiple revalidateTag()'s in an API handler only revalidates 1 tag. Or I'm doing smth wrong.

revalidateTag(body._type);
    if (body.slug) {
      revalidateTag(`${body._type}:${body.slug}`);
    }

Given having both a body._type & body.slug it only revalidates one of them.

Edit: Timple query tags (tags: [job]) are the ones NOT working and the complex ones are (tags: [job:${params.slug}]) which is even more suprising.

The issue is NOT multiple revalidateTag() calls, but something with the fetch tags.

22 Replies

Avatar
risky
im confused here, you are currently having one tag that's name is made from 2 vars...?
Avatar
Jersey WoolyOP
Yes. I use an API route that gets called from a Sanity webhook whenver the content changes in the CMS.

Here's the route handler:
export async function POST(req: NextRequest) {
  try {
    const { body } = await parseBody(req);

    if (!body?._type) {
      const message = "Bad Request";
      return new Response(JSON.stringify({ message, body }), { status: 400 });
    }

    // If the `_type` is `page`, then all `{next: {tags: ['page']}}` will be revalidated. If `slug` included, all 'page' and 'page:slug' tags.
    revalidateTag(body._type);
    if (body.slug) {
      revalidateTag(`${body._type}:${body.slug}`);
    }

    return NextResponse.json({
      status: 200,
      revalidated: true,
      now: Date.now(),
      body,
    });
  } catch (err: any) {
    console.error(err);
    return new Response(err.message, { status: 500 });
  }
}


and 2 of my fetches from different components on different pages:
  const jobs = await sanityFetch<Job[]>({
    query: jobsQuery,
    tags: [`job`],
  });


  const page = await sanityFetch<Job | null>({
    query: jobBySlugQuery,
    params: { slug: params.slug },
    tags: [`job:${params.slug}`],
  });


Note: sanityFetch is just a wrapper around fetch() with a sanity client
Avatar
risky
If the _type is page, then all {next: {tags: ['page']}} will be revalidated. If slug included, all 'page' and 'page:slug' tags.
i don't think this is correct... you only have one tag in your example... otherwise you should add more in the tag list in fetch
hmm actually looking at your example, it looks correct...?
Avatar
Jersey WoolyOP
When the API route gets called, it runs and I receive a success response.
{
  "id": "atm-xxx",
  "projectId": "xxx",
  "inProgress": false,
  "duration": 2760,
  "createdAt": "2023-09-23T14:32:41.886Z",
  "updatedAt": "2023-09-23T14:32:41.886Z",
  "messageId": "msg-xxx",
  "hookId": "xxx",
  "isFailure": false,
  "failureReason": null,
  "resultCode": 200,
  "resultBody": "{\"status\":200,\"revalidated\":true,\"now\":1695479564241,\"body\":{\"_type\":\"job\",\"slug\":\"product-engineer-with-next-js-expertise-2023-08-30t12-53-00-000z\"}}"
}
Avatar
risky
are you sure that your sanityFetch actually passes on the tags to fetch req
Avatar
Jersey WoolyOP
yes, I'm sure. because 1 tag always gets revalidated. Usually the one with slug included job:${params.slug}. But the simple job tag doesn't. Aka: the job/[slug] page receives the new data on refresh but the homepage, listing all jobs (simple job tag) does not
(btw thanks for taking time out of your weekend to debug cache issues for a rando guy on the internet lol)
Avatar
risky
you should be-able to revalidate multiple tho...
i see your issue
i think this could be from your homepage having its own page cache
like use revalidatePath also
Avatar
Jersey WoolyOP
well, sometimes I can't see the new data at all. lol. I'm working on it currently, trying to figure out what's going on. And now I can't see anything changed on the site, although the api route succeeded.
Avatar
risky
like either use revalidatePath for homepage or export const revalidate = 0 for it... this may give newer data
as nextjs could be caching the page as it thinks its static
Avatar
Jersey WoolyOP
I thought revalidatePath wouldn't make sense in my case because I render the same components on multiple pages. Example: a job post of a remote, EU based, part-time product engineer.
That should render on:
- homepage
- /location/eu page
- /contract/part-time page
- /type/remote page
- /job/[slug] page
- etc..
Avatar
risky
then disable page level caching (fetch would be cached still)
actually i think you can attach tags to pages too (im not fully sure actually) - i can't find anything, so ill asume not
Avatar
Jersey WoolyOP
but yeah, using revalidatePath at least the homepage might make more sense. Also, I'm trying to figure out if I need generateStaticParams for dynamic routes or don't when using revalidate*
the funny thing is that generateStaticParams makes no difference in the revalidation issue. I'm working on 2 projects right now where I try to figure out this stuff. And 1 is using generateStaticParams & revalidatePath the other is just revalidatePath. And there's no difference. 😄
Avatar
Jersey WoolyOP
fyi: I think I figured that the simple query tags (tags: [job]) are the ones NOT working and the complex ones are (tags: [job:${params.slug}]) which is even more suprising now. lol.
Avatar
Jersey WoolyOP
@Alfonsus Ardani I see you were active recently in similar discussions, so I thought you might have some ideas whenever you have some time