Closed leerob closed 1 year ago
Title: Issue in preview branches but not present after merging or deploying to production
Description:
I have encountered an issue that consistently occurs in preview branches but is not present once the branch is merged or deployed to production.
Reproducible Scenario:
Preview URL
Expected Result: The behavior should be consistent between the production and preview branches.
Additional Information:
Repository: https://github.com/Diabl0570/next-revalidate-test "Production" URL: https://next-revalidate-test-nu.vercel.app/pokemon Preview URL: https://next-revalidate-test-git-feat-commit-diabl0570.vercel.app/ PR URL: https://github.com/Diabl0570/next-revalidate-test/pull/3
@leerob I see the issue is closed, should I create a new issue?
I would like to add my thoughts on this issue. I tried to make the revalidatePath
function work on Vercel. The revalidate action is fired after saving a Post or page returning a console log of the edited content with status code 200. Working on A Sanity CMS project and I am 100% sure there is this bug inside the Next app router. Where, the export const dynamic = 'auto'
which if we have to believe the Next js documentation enabled by default. This is not true, tried refactoring my code for days to figure out what was going on. After 7 days tried to use the export const dynamic = 'auto'
and after deploying to Vercel it works perfectly fine for all dynamic routes. It will instantly display and generate a new static file after making changes. GenerateStaticParams only creates and works after building the application after that, nothing will work or display new data at all.
Hope this helps...
It's also an issue when using fetch with { cache: 'no-store' } setting to fetch data from your local Next API. One work around I found was to make sure you have POST and GET requests stubbed out in your API route.js file. When I only had GET specified it failed to get the most up-to-data data from the API call until I fully rebuilt the production next app (npm run build ; npm run start)
so you mean that it's necessary change the name of the function inside the route.js from GET to POST also when it's not necessary catch params in input?
No, just need to have both specified. I found if I only have POST in the route.js, it didn't return the most recent data until I specified GET as well. The GET function doesn't need to do anything, it just needs to be stubbed.
i.e.
export async function POST(request) { return NextResponse.json(latestData) } export async function GET(request) { return NextResponse.json({}) }
OH! Thank you. I tried doing something like this on a whim and it actually fixed my issue. In my case, I already had a get and I just exported a POST and now next is respecting no-store and I am getting fresh data. Otherwise, none of these options do anything
export const fetchCache = 'force-no-store'
export const revalidate = 0 // seconds
export const dynamic = 'force-dynamic'
Here's what I added:
export const POST = async (req: Request) => {
return NextResponse.json({error: 'Method not allowed'}, {status: 405})
}
export const revalidate = 0
doesn't work for me with server component pages and Prisma. The data isn't being updated when navigating back and forth or via <Link>
components.
// page.js
export const revalidate = 0
async function getData() {
return await prisma.post.findMany(...)
}
export default async function Page() {
const data = await getData()
return (
<>
{data.map(
...
}
</>
)
}
Workaround atm: Call revalidate(path)
after mutating the data
well, in actuality I am fetching from a graphql endpoint of a local headless CMS (Strapi). It's harder to share as a working code but it's really a completely standard fetch routine in
app/page.tsx
, and no changes to the abovepages/api/revalidate.ts
, something likeimport { ApolloClient, InMemoryCache, gql } from "@apollo/client"; import moment from "moment"; const client = new ApolloClient({ uri: "http://localhost:1337/graphql", cache: new InMemoryCache(), ssrMode: typeof window === "undefined", name: "react-web-client", connectToDevTools: true, defaultOptions: { watchQuery: { fetchPolicy: "no-cache", errorPolicy: "ignore"}, query: { fetchPolicy: "no-cache", errorPolicy: "all" } }}); async function getData() { const { data, error } = await client.query({ query: gql`{ front { data { id attributes { updatedAt }}}}`,}); return data;} export default async function Home() { const strapidata = await getData(); return (<h1> Strapi updatedAt: {moment(strapidata.front.data.attributes.updatedAt as string).format("HH:mm:ss")} </h1> ) }
The cache options in the Apollo client were part of my debugging (in v13.2.x), but I don't think they are essential (anymore). I have not tested again, but it worked in 13.3.0, and should also in latest canary.
@jwalcher I have exactly the same setup and the same issue. The difference is that in my case it works locally but not in production (Vercel). Did you manage to fix this?
You mean the issue with middleware breaking res.revalidate? I basically left the app at 13.3.0 where everything works fine. My plan is to refactor, using fetch() instead of apollo once revalidatePath works on dynamic routes https://github.com/vercel/next.js/issues/49387 (I hope that's not never). I'm self hosting, can't comment on Vercel issues.
No, not middleware. Pages router with getStaticProps using Strapi. I only get the new posts when i re-deploy.
For me both revalidatePath
and revalidateTag
works on 13.4.10
but NOT on 13.4.12
.
Following basic examples from Next docs
@tobbbe not 100% certain, but maybe this is related to current cache invalidation bugs (since next@13.4.11-canary.1
):
@jwalcher I have exactly the same setup and the same issue. The difference is that in my case it works locally but not in production (Vercel). Did you manage to fix this?
Same setup here :
Revalidate api route + revalidate : 0
Working on Dev but seems to be impossible to refresh data when deploy/build into Vercel.
Please, for the love of donuts, do NOT make caching the default. For 6 months now, since using Next.js 13, I CANNOT REVALIDATE MY DATA IN PRODUCTION!
I've tried revalidatePath, export const revalidate = true, export const revalidate = 0, export const dynamic = 'force-dynamic', refreshing the page each time the user visits the page. Nothing works. My data won't update. I've spent 6 months building this product for a big client and I can't get the data on the screen to update in production.
Caching should NOT be the default behavior. It should be optional.
Hey folks, small update here. Since this issue has been posted, we've fixed a number of bugs with revalidation in the App Router. Further, we have published brand new caching documentation that goes in depth on fetching, caching, and revalidating:
Going forward, we can't look into any issues mentioned unless there's a reproduction provided. If you are still seeing an issue, please create a minimal repro and open a new issue. Thank you! 🙏
Moved from https://github.com/vercel/next.js/discussions/42290
Edit: Updated Reply
Hey folks, small update here. Since this issue has been posted, we've fixed a number of bugs with revalidation in the App Router. Further, we have published brand new caching documentation that goes in depth on fetching, caching, and revalidating:
Going forward, we can't look into any issues mentioned unless there's a reproduction provided. If you are still seeing an issue, please create a minimal repro and open a new issue. Thank you! 🙏