Next.js Discord

Discord Forum

My SSC doesn't show updated Sanity data

Answered
Northern Mockingbird posted this in #help-forum
Open in Discord
Northern MockingbirdOP
I have a simple Server-Side Component that fetches data from Sanity and then renders it.

export default async function StorePage() {
  const items = await client.fetch(`*[_type == "storeItem"]`);
  return (...)


Each item has a amountInStock attribute set as a number. A user purchases an object, so I subtract the quantity from the amountInStock and patch() it to Sanity to update the item's value:
await client
  .patch(sanityProduct._id)
  .set({ amountInStock: newAmount })
  .commit();


It works, but my SSC does not display the updated item details until I reset cache/hard refresh.

What am I missing?
Answered by Ray
I think you need to revalidate there.
create an api route and either use revalidateTag or revalidatePath.
also, you could set a tag in the fetch function like this
export default async function StorePage() {
  const items = await client.fetch(
    `*[_type == "storeItem"]`,
    {},
    { next: { tags: ["store-page"] } }
  );

  return ...
}

and do this in the api route
export function GET(req: Request) {
    revalidateTag('store-page')
    return Response.json({ revalidated: true })
}
View full answer

15 Replies

@Northern Mockingbird I have a simple Server-Side Component that fetches data from Sanity and then renders it. export default async function StorePage() { const items = await client.fetch(`*[_type == "storeItem"]`); return (...) Each item has a `amountInStock` attribute set as a number. A user purchases an object, so I subtract the quantity from the amountInStock and patch() it to Sanity to update the item's value: await client .patch(sanityProduct._id) .set({ amountInStock: newAmount }) .commit(); It works, but my SSC does not display the updated item details until I reset cache/hard refresh. What am I missing?
I think you need to revalidate there.
create an api route and either use revalidateTag or revalidatePath.
also, you could set a tag in the fetch function like this
export default async function StorePage() {
  const items = await client.fetch(
    `*[_type == "storeItem"]`,
    {},
    { next: { tags: ["store-page"] } }
  );

  return ...
}

and do this in the api route
export function GET(req: Request) {
    revalidateTag('store-page')
    return Response.json({ revalidated: true })
}
Answer
this is just a simple example, you should do some verification in the api route to prevent unauthorized revalidation
so after you update the content on sanity, you need to make a request to the api route for revalidation. I think you could setup webhook on the sanity dashboard
Northern MockingbirdOP
Hey, checking on this now. Thanks for replying.
Northern MockingbirdOP
Wow, it worked perfectly.

I created the api route:
import { NextResponse } from 'next/server';
import { revalidateTag } from 'next/cache';

export async function GET() {
  revalidateTag('store-page');
  return NextResponse.json({ revalidated: true });
}


And then I just call that after the user purchases a product
async function revalidateSanityData() {
  try {
    const response = await fetch('/api/store', { method: 'GET' });
    const data = await response.json();
  } catch (error) {
    console.log('Revalidate Sanity Data Error: ', error);
  }
}


It's updating the product's "amountInStock" properly by me just navigating to the new page. Thank you so much man.
Just two questions about two things you mentioned, "do some verification in the api route" and "setup webhook in sanity dashboard".

What kind of verification you think?
And What would the webhook be doing in Sanity dashboard?
Actually, sorry. Third question.

So that solution revalidates the data when the data is updated from app -> sanity. What about if the sanity data gets updated by the app owner?

Should I call that "GET" method on the store index page as well? Like revalidate every time that page gets visited ?
Northern MockingbirdOP
Something like this?
const response = await fetch('/api/store', {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${process.env.NEXT_PUBLIC_API_KEY}`,
  },
});


export async function GET(req) {
  revalidateTag('store-page');
  if (
    req.headers.authorization === `Bearer ${process.env.NEXT_PUBLIC_API_KEY}`
  ) {
    return NextResponse.json({ revalidated: true });
  }
}


It's wrong but I'm not sure how to access the header value from within "GET". I should know this but my brain is fried I guess