vercel / commerce

Next.js Commerce
https://demo.vercel.store
MIT License
11.48k stars 4.24k forks source link

Doesn't revalidate a cart revalidate it for all customers? #1278

Closed mastoj closed 7 months ago

mastoj commented 10 months ago

Looking through the code and have a question around revalidateTag(TAGS.cart). Since the same tag is used for all carts, won't that revalidate all carts? Shouldn't the tag also include cart id or something to narrow it down to that specific customers cart to avoid more fetches than needed?

carstenblt commented 10 months ago

Exactly my thoughts.

osseonews commented 9 months ago

The cart operation is sent with the header, cache: 'no-store', so unless I'm missing something, nothing in the cart is cached, so there is nothing to revalidate and you would never do revalidation on a cart. You just call the functions again to get a new cart etc. The cookie with the cartId is sent in the request.

As an aside, I wouldn't do Cart operations on the server, like this repo does, but that's another discussion.

leerob commented 7 months ago

The fetch to retrieve the latest cart items always grabs the most up-to-date data, using no-store. However, when doing a mutation (like adding to cart), you still want to call revalidateTag to clear the entire Next.js router cache, so you'll see the updated cart values when navigating between pages. If you were to reload the page, you would go back to the fresh fetch with no-store to get the latest cart data. But you're right, we could make the cache tag even more specific if we wanted to!

zipme commented 4 months ago

hi @leerob , thanks for the answer! In your example, you opted not to cache the cart data by using ‘no-store’ with the fetch function, but you still applied the tag to enable route cache revalidation. I’m curious if there’s a way to achieve similar functionality using unstable_cache. Specifically, is it possible to mark or tag the function call without actually caching the data?

Additionally, when utilizing a custom cache handler, such as the one provided here, my understanding is that even if the data is not cached, calling revalidateTag from a server action will still trigger the revalidateTag function of this custom cache handler. Is that correct?

zipme commented 4 months ago

According to this doc:

In a Server Action: Revalidating data on-demand by path with (revalidatePath) or by cache tag with (revalidateTag) Using cookies.set or cookies.delete invalidates the Router Cache to prevent routes that use cookies from becoming stale (e.g. authentication).

Here is the workaround I am using:

// serverHelper.ts
import "server-only";

export const revalidateRouteCache = () => {
  cookies().delete("random");
};
// action.ts
"use server"
export async function addItem(...) {
  ...
  // revalidateTag(TAGS.cart);
  revalidateRouteCache();
}