skip to Main Content

Here is the website that I just deployed on Vercel. I am building a web application using Prisma and Next.js, and I’m experiencing an issue where the content is not updating in real-time until I manually re-deploy the application. Here’s the scenario:

  • I have an API endpoint in my Next.js app that fetches data from a Prisma database.
  • When I create or update data in the database through the application, the changes are reflected immediately in the development environment, but they are not reflected in the production environment until I re-deploy the application.

This is how I get my data on the front-end:

const { data: posts, error } = useSWR(`/api/getPosts`, fetcher, {refreshInterval:1000});

This is the API endpoint to post the content :

// Addposts to prisma backend

import { NextResponse, NextRequest } from 'next/server';
import prisma from '../../../prisma/client';

// Function

export async function POST(request:NextRequest) {
    const data = await request.json();
    const title = data.title;
    const user = await prisma.user.findUnique({
        where: {
            email : data.email
        }
    })
    if (!user){
        // return error
        return NextResponse.json({error: "User not found"}, {status: 404})
    }

    if (!title){
        // throw error
        return NextResponse.json({error: "Title is required"}, {status: 400})
    }

    if (title.length > 300){
        return NextResponse.json({error:"Title should not be more than 300 characters"}, {status:400});
    }
    const userId = user?.id;

    const post = await prisma.post.create({
        data: {
            title,
            userId
        }
    })
    try{
        return NextResponse.json({post},{status:200})
    }catch(error){
        return NextResponse.json({error}, {status:500})
    }
}


API endpoint to get all the posts:

import { NextRequest, NextResponse } from 'next/server'
import prisma from '../../../prisma/client'
import { NextApiResponse } from 'next';


export async function GET(request:NextRequest){
    const posts = await prisma.Post.findMany({
        include: {
            user: true
        },
        orderBy:{
            createdAt: 'desc'
        }
    })
    try{
        // return all the posts
        return NextResponse.json({posts},{status:200})
    }catch(error){
        return NextResponse.json(error, {status:500});
    }
}

How can I ensure that the content updates are immediately reflected in the production environment without the need for manual re-deployment?

Here is the link to the GitHub repo.

UPDATE

I am able to make POST request and make changes to the db, I think the problem has to be with the GET request

Any insights or suggestions would be greatly appreciated. Thank you!

2

Answers


  1. This issue seems to be caused by default caching used by Next.js 13+. Your fetch requests are by default cached – https://nextjs.org/docs/app/building-your-application/data-fetching/fetching#static-data-fetching.

    Login or Signup to reply.
  2. const { data: posts, error } = useSWR(/api/getPosts, fetcher, {refreshInterval:1000});

    That means you are using SWR, the React hook for data fetching.

    I see SWR has a mutation function which would be of interest: You can use mutate() function of SWR to update cache and re-fetch the data.

    From your repository Sadeedpv/tweet-it, I see you have a app/components/InputField.tsx, which handles the submit function. It makes a POST request to your /api/addPosts endpoint

    You can modify the handleSubmit function to also revalidate the SWR cache after the post is created, like so:

    import { mutate } from 'swr'; // <-- import mutate from SWR
    
    // ...
    
    const handleSubmit = async (e: React.FormEvent) => {
      e.preventDefault();
      setPost('');
      setDisabled(true);
      toast('Posting...');
    
      try {
        await axios.post("/api/addPosts", {
          title: post,
          email: session?.user?.email,
        });
    
        mutate('/api/getPosts'); // <-- revalidate SWR cache here
    
        setDisabled(false);
        toast.success('Successfully posted');
      } catch (err) {
        toast.error(err.response.data.error);
      }
    };
    
    // ...
    

    By calling mutate('/api/getPosts'), you are telling SWR to revalidate the data at the /api/getPosts endpoint. That should ensure that your list of posts is immediately updated in your app once a new post is successfully created.

    The rest of your InputField.tsx component can stay the same.

    When you call mutate('/api/getPosts') in your InputField component, you are using a "mounted SWR hook using the same key" (/api/getPosts), as per the SWR documentation. That means that the cache will be updated, and a revalidation will be triggered, which is what you might need here.


    That might be lighter on your server than include a ‘no-store’ cache option in your fetch request, like:

    const fetcher = async (url: string) => {
      const response = await fetch(url, { cache: 'no-store' });
      const data = await response.json();
      return data.posts;
    };
    

    If you find that your app is serving stale data due to Next.js’s default caching behavior, you could use the no-store option to bypass the cache and always fetch fresh data from the server.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search