Search code examples
next.jsvercel

Data not updating when deployed Nextjs13 app on Vercel, despite using cache: 'no-store' in fetch request


I have a feed component in my application that fetches data from an API endpoint. The component works fine when I test it on my local build, but when I deploy it on Vercel, it doesn't fetch the latest data. I suspect this issue is related to caching. To address the problem, I added the cache: 'no-store' option to the fetch request, but it doesn't seem to solve the problem. I would appreciate any help or suggestions to resolve this issue.

"use client";

  const fetchPosts = async () => {
    const response = await fetch("/api/prompt", {
      cache: 'no-store',
    });
    const data = await response.json();
    setAllPosts(data);
  };

  useEffect(() => {
    fetchPosts();
  }, []);

GitHub Link: https://github.com/justinwkUKM/promptify/blob/main/components/Feed.jsx

Note: Please provide any suggestions or solutions for the caching issue when deploying on Vercel. Thank you!


Solution

  • For anyone who is still encountering this issue when deploying to Vercel:

    The issue is being caused by the file being rendered statically by Next.JS. According to the documentation: By default, Next.js statically renders routes to improve performance.

    You can see this in the output printed when npm run build is executed. A simple example of the output is shown below.

    Route (app)
    ┌ ○ /api/prompt
    └ λ /api/prompt/[id]
    
    λ  (Server)  server-side renders at runtime (uses getInitialProps or getServerSideProps)
    ○  (Static)  automatically rendered as static HTML (uses no initial props)
    

    In order to prevent Next.JS from statically rendering this site it needs some way to know its dynamic. According to the documentation: if a dynamic function or a dynamic fetch() request (no caching) is discovered, Next.js will switch to dynamically rendering the whole route at request time.

    The static and dynamic behavior of a route can be controlled using the Route Segment Config features of Next.JS

    Specifically you can export the dynamic variable with the value of 'force-dynamic' as shown

    import Prompt from "@models/prompt";
    import { connectToDB } from "@utils/database";
    
    export const dynamic = 'force-dynamic';
    export const GET = async (request) => {
      try {
        await connectToDB();
    
        const prompts = await Prompt.find({}).populate('creator');
    
        return new Response(JSON.stringify(prompts), { status: 200 });
      } catch (error) {
        return new Response("Failed to fetch all prompts", { status: 500 });
      }
    } 
    

    This export ensures that Next.JS renders the route dynamically!

    A little side note: This is functionally similar to adding export const revalidate = 0; according to the docs.