Issue with Next.js revalidation
Describe the bug
https://sanity-io-land.slack.com/archives/C9Z7RC3V1/p1718675586121679
I am getting Failed to parsed response body as JSON: Unexpected non-whitespace character after JSON at position 820 on production builds of my site. On the build that was successful to production and currently live, if I try to rebuild it throws these errors now.
I am using Next.j 14.2.3.
fetch.ts
import type { ClientPerspective, QueryParams } from "next-sanity";
import { draftMode } from "next/headers";
import { client } from "@/sanity/lib/client";
import { token } from "@/sanity/lib/token";
/**
* Used to fetch data in Server Components, it has built in support for handling Draft Mode and perspectives.
* When using the "published" perspective then time-based revalidation is used, set to match the time-to-live on Sanity's API CDN (60 seconds)
* and will also fetch from the CDN.
* When using the "previewDrafts" perspective then the data is fetched from the live API and isn't cached, it will also fetch draft content that isn't published yet.
*/
export async function sanityFetch<QueryResponse>({
query,
params = {},
perspective = draftMode().isEnabled ? "previewDrafts" : "published",
/**
* Stega embedded Content Source Maps are used by Visual Editing by both the Sanity Presentation Tool and Vercel Visual Editing.
* The Sanity Presentation Tool will enable Draft Mode when loading up the live preview, and we use it as a signal for when to embed source maps.
* When outside of the Sanity Studio we also support the Vercel Toolbar Visual Editing feature, which is only enabled in production when it's a Vercel Preview Deployment.
*/
stega = perspective === "previewDrafts" ||
process.env.VERCEL_ENV === "preview",
}: {
query: string;
params?: QueryParams;
perspective?: Omit<ClientPerspective, "raw">;
stega?: boolean;
}) {
if (perspective === "previewDrafts") {
return client.fetch<QueryResponse>(query, params, {
stega,
perspective: "previewDrafts",
// The token is required to fetch draft content
token,
// The `previewDrafts` perspective isn't available on the API CDN
useCdn: false,
// And we can't cache the responses as it would slow down the live preview experience
next: { revalidate: 0 },
});
}
return client.fetch<QueryResponse>(query, params, {
stega,
perspective: "published",
// The `published` perspective is available on the API CDN
useCdn: true,
// Only enable Stega in production if it's a Vercel Preview Deployment, as the Vercel Toolbar supports Visual Editing
// When using the `published` perspective we use time-based revalidation to match the time-to-live on Sanity's API CDN (60 seconds)
next: { revalidate: 60 },
// The token is required as we are using a private dataset
token,
});
}
client.ts
import { createClient } from "next-sanity";
import { apiVersion, dataset, projectId, studioUrl } from "@/sanity/lib/api";
export const client = createClient({
projectId,
dataset,
apiVersion,
useCdn: true,
perspective: "published",
stega: {
studioUrl,
// logger: console,
filter: (props) => {
if (props.sourcePath.at(-1) === "title") {
return true;
}
return props.filterDefault(props);
},
},
});
To Reproduce
Steps to reproduce the behavior:
- git clone https://github.com/codercatdev/cms-sanity
- git checkout next-issue-1599
- pnpm i
- pnpm dev
- hit a route like http://localhost:3000/author/nick-rouech
Expected behavior
I would expect JSON not to contain any extra whitespace.
Screenshots
Which versions of Sanity are you using?
@sanity/cli (global) 3.46.1 (up to date) @sanity/assist 3.0.4 (up to date) @sanity/code-input 4.1.4 (up to date) @sanity/icons 3.2.0 (up to date) @sanity/image-url 1.0.2 (up to date) @sanity/preview-url-secret 1.6.17 (up to date) @sanity/ui 2.4.0 (up to date) @sanity/vision 3.46.1 (up to date) @sanity/webhook 4.0.4 (up to date) sanity 3.46.1 (up to date)
What operating system are you using? Mac 14.5 (23F79)
Which versions of Node.js / npm are you running? 10.8.1 v22.3.0
Additional context
I thought at first this was a stega issue as it seems to be related, but if I fetch with stega:false it still happens. Setting next:revalidate to 0 is the only thing that I found works.
The only change from the example is that when using the "published" perspective I also pass token as my dataset is not public.
Okay I have narrowed this issue down to this setting in the next-sanity package of the client.
next: { revalidate: 60 },
fetch.ts
return client.fetch<QueryResponse>(query, params, {
stega,
perspective: "published",
// The `published` perspective is available on the API CDN
useCdn: true,
// Only enable Stega in production if it's a Vercel Preview Deployment, as the Vercel Toolbar supports Visual Editing
// When using the `published` perspective we use time-based revalidation to match the time-to-live on Sanity's API CDN (60 seconds)
next: { revalidate: 60 },
// The token is required as we are using a private dataset
token,
});
The only time I get good data is setting next: { revalidate: 0 },
Thank you for making the effort to create a good repro for this. We'll have a look as soon as we get our hands free.
@evenwestvang I am seeing issues that surround cloudinary.asset when this field is included at times the object fails and doesn't come back with data at all. I am not 💯 if this is related to the other issues or not.
GROQ
*[_type == "podcast" && views > 0]|order(views desc)[0...4]{
coverImage
}
Example in Next.js not returning this field
Vision returns all of the data correctly, I am wondering if this could cause any of the whitespace as well, or if something isn't correct with the JSON. Since I have images all over the site from Cloudinary I obviously would see all the issues mentioned above.
Full JSON of the result from vision query-result.json
Some more groq tests with cloudinary becoming an issue. I will also add that even if I try to just use the below it still goes missing inside of Next.js.
coverImage{
public_id,
},
with-cloudinary.json - missing entries without-cloudinary.json - all entries valid
Again with these in vision or CLI it works.
okay all of what I thought were issues with cloudinary.asset was not, it appears that is all due to a problem using taint.
simple repo: https://github.com/codercatdev/next-sanity-cloudinary-issue
This shows how the logger displays when using taint vs. the data actually appearing on the page. These two things DO NOT match.
The issue with Failed to parsed response body as JSON: Unexpected token '/', "/ still remains with any type of revalidate set on the client.
I will pay for support to get this working @evenwestvang @kmelve is there someone I can do a call with to get this working. It is forcing me out of static and only allowing for a lambda based site, which I was hoping to avoid.
@codercatdev is this issue still for grab?
@Shub3am yes it should be, if you can't repro let me know and I will make sure that branch is usable for the issue.
Sure, I am taking this one
Any workaround to this issue?
My only workaround was to stop generating anything statically. Not really a great workaround but for now that is what I have. So all of https://codingcat.dev is on demand.
Same here, I only get this in dev environment
On Fri, 26 Jul 2024, 11:41 am Dante, @.***> wrote:
This only affects me during dev, not production. However none of the workaround are working for me.
— Reply to this email directly, view it on GitHub https://github.com/sanity-io/next-sanity/issues/1599#issuecomment-2252485507, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHXXP7FD34ZRJA7VGKESXY3ZOIRVZAVCNFSM6AAAAABJQDXA62VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENJSGQ4DKNJQG4 . You are receiving this because you are subscribed to this thread.Message ID: @.***>
We are running into this same issue running app router and 15.0.4. @codercatdev did you ever figure out what was going on? We found a workaround by wrapping the whole thing in unstable_cache and using its revalidation logic instead. That has seemed to work but seems silly since its baked into fetch.
Unfortunately no 😔
On Fri, Jan 17, 2025, 7:54 PM Justin Adkins @.***> wrote:
We are running into this same issue running app router and 15.0.4. @codercatdev https://github.com/codercatdev did you ever figure out what was going on? We found a workaround by wrapping the whole thing in unstable_cache and using its revalidation logic instead. That has seemed to work but seems silly since its baked into fetch.
— Reply to this email directly, view it on GitHub https://github.com/sanity-io/next-sanity/issues/1599#issuecomment-2599432472, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAXVMKN34WBU7XI47DRKJ532LGQ5LAVCNFSM6AAAAABVM7OPWOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKOJZGQZTENBXGI . You are receiving this because you were mentioned.Message ID: @.***>
I have the same issues but in dev environment. Building works fine. Everytime next fast refresh is triggered it throws a similar error.
I was able to fix my errors by changing the node version with nvm. i used v22.13.1 and got errors. On v20.18.1 the errors do not occur
I was able to fix my errors by changing the node version with nvm. i used v22.13.1 and got errors. On v20.18.1 the errors do not occur
You have saved my life, the past 2 months I was stuck on this annoying bug. I changed back and forth node, react and next versions