vercel / next.js

The React Framework
https://nextjs.org
MIT License
126.8k stars 26.95k forks source link

Revalidation not working in deployment mode #56231

Open obtusei opened 1 year ago

obtusei commented 1 year ago

Link to the code that reproduces this issue

https://github.com/obtusei/nextjs-test

To Reproduce

My Code:

async function getPosts() {
  try {
    const getData = await fetch(`${process.env.BACKEND_URL}/wp-json/wp/v2/posts`, {
      next: {
        revalidate: 20,
      },
    });

    const data = await getData.json();
    return data;
  } catch (err) {
    console.log(err);
  }
}

export default async function Home() {
  const posts = await getPosts();
  return (
    <main className="p-10">
      <h1 className="text-4xl">Posts</h1>
      <br />
      <div className="flex flex-col gap-4">
        {posts.map((post: any) => {
          return (
            <Link
              href={`/posts/${post.id}`}
              key={post.id}
              className="border-2 border-gray-500 p-4 rounded-xl"
            >
              <h2 className="text-xl font-semibold">{post.title.rendered}</h2>
              <div
                className="text-gray-300"
                dangerouslySetInnerHTML={{ __html: post.content.rendered }}
              />
            </Link>
          );
        })}
      </div>
    </main>
  );
}

Current vs. Expected behavior

Expected Behavior: Posts to be revalidated every 10 seconds in deployment. If the posts are updated in backend, they should also be updated in nextjs application after 10 seconds.

Observed behavior The posts are updated in backend, they aren't being updated in nextjs application after 10 seconds. (In Deployment/Production Mode)

Verify canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: x64
  Version: Darwin Kernel Version 21.6.0: Thu Jun  8 23:57:12 PDT 2023; root:xnu-8020.240.18.701.6~1/RELEASE_X86_64
Binaries:
  Node: 18.16.0
  npm: 9.6.5
  Yarn: 1.22.19
  pnpm: 8.6.5
Relevant Packages:
  next: 13.5.3
  eslint-config-next: 13.5.3
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.2.2
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Data fetching (gS(S)P, getInitialProps)

Additional context

No response

MAhmedSid commented 1 year ago

I am also getting the same issue and I am using next v13.4.19 . It is literally a headache that I have tried every single solution for that even I have used no-store instead of doing cache. It also stucks. Data fetching is still an issue. Next js team should work on that ASAP as it is disturbing many production sites.

sferdeveloper commented 1 year ago

We have the same issue next: 13.5.4 . I thought we were doing something wrong 😑

sferdeveloper commented 1 year ago

Since this happens to us in a project that is really important, we had to find out a solution -- not the best solution, but it does the job

All we did is change the request method to PUT request , here is , how I did,:

This is the function that fetches data and runs in the server:


const getAvailableTasks = async () => {
  try {
    const res = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}api/tasks`, {
      cache: "no-store",
      method: "PUT", // change GET to PUT
      next: { revalidate: 0 },
    });

    if (!res.ok) {
      throw new Error("Failed to fetch topics");
    }
    const availableTasks = await res.json();
    return availableTasks;
  } catch (error) {
    console.log("Error loading topics: ", error);
  }
};

And this the controller that fetch the data, must be PUT too


connectDB();

// ? GET all available tasks

export async function PUT(request: NextRequest) {
  try {
    // TODO : find user county => get tasks for them ...

    // const userID = await getDataFromToken(request);

    // const user = await User.findOne({_id: userId}).select("-password");

    const availableTasks = await Task.find();

    return NextResponse.json(availableTasks);
  } catch (error: any) {
    return NextResponse.json({ error: error.message }, { status: 400 });
  }
}

This is our temporary solution until NextJS team fix the bug.

@obtusei @MAhmedSid

sferdeveloper commented 1 year ago

I have got solution by removing all redirect domains to the main domain in vercel project domain setting.

Wow, please give more details on how to do it, I'm dealing with this issue 3 days now! Where I can fin that?

Thanks, MAhmed!

MAhmedSid commented 1 year ago

If you are using turbo then make cache false in turbo.json. And other thing is try purging cache of project in settings of project on vercel. And check docs of cache they recently updated.

sferdeveloper commented 1 year ago

I think it's not Vercel problem, if you try to build locally and run yarn start it will be statically generated. We just found a solution : we send httpOnly cookie with the GET request and that fixed the issue 😃

GET request with httpOnly cookie => extract userID from the cookie => send them data

Finally 😴

MAhmedSid commented 1 year ago

So will that also work with time based revalidation. Because sometimes its also not gotta work.

phil221 commented 1 year ago

Also seeing @obtusei's exact issue using headless WP, would greatly appreciate updates. I am eventually seeing the in-app updates for both WP post creation and post updates, but they take anywhere from 5 minutes to 30 to actually propagate. Apparently the default WP REST API cache expiry settings can sometimes affect this, but in my case I can see the updates immediately after publishing when I fetch via a client service like Insomnia - so the WP cache seems to not be a factor here.

ricardomarsanc commented 3 months ago

Same happening here! I want an API request to be done every 12 hours, to avoid reaching the monthly limit of the API as much as possible. What I'd expect is that every 12 hours the data is marked as stale, and if I (from my computer) navigate to the page, I receive the old data, then server will re-fetch the data as it is stale, and if I do an F5 I should get the most recent data (or maybe just by navigating from my phone or something like that).

What is happening is that for some time after the first deployment it worked, then it was like 6 days in a row (if it is every 12h I can assume it had 12 opportunities to mark data as stale) without working fine. Even after a new deployment (locally it worked perfectly, so as build + start), data was not updated, but suddenly 40 min after the new deployment, after reloading the latest data was there.

What I want is that the server marks as Stale the data every 12h, and if a new user navigates to the page, the server fetches the new data if stale, and if not, returns the actual one. Am I missing something and shouldn't it work like that? Am I crazy and it couldn't even work for those first two days and I just hallucinated?

Lucky me this is a pet project, but after looking into the issue for a while, it was kind of clear that there's some issue with the revalidate option in Next 14 (app router), and also it is a very obscured feature which is very difficult to debug (not sure if even possible), to see what's happening in the background in a production-like environment.