Next.js V13: revalidate not triggering after router.push
Asked Answered
S

2

9

I'm using Next.js version 13 app route and am having trouble with the revalidate feature not triggering after a router.push call.

In my project, I allow users to create blog posts on the /blog/create page. If the post is successfully added to the database, I use router.push to navigate to the /blog page.

However, after the navigation, it seems that the /blog page is still using the old data and revalidate is not triggering to fetch the updated data.

Therefore, the new post is not displayed.

I've tried setting revalidate to 0 of the /blog page to ensure that the data is fetched via server-side rendering, but it doesn't seem to work.

Currently, I can only see the new blog post by hard refreshing the /blog page or by clicking the navbar button to navigate to the /blog page again.

Is there a way to force revalidate to trigger after a router.push call or a workaround for this issue? Any help would be greatly appreciated. Thank you!

/blog, page.tsx:

export const revalidate = 0;
//export const fetchCache = "no-cache";

async function getData() {
  const postsDocRef = collection(firestore, "posts");
  const q = query(postsDocRef, orderBy("createdAt", "desc"), limit(10));
  const data = await getPosts(q);

  return data;
}

const Blogs = async (): Promise<JSX.Element> => {
  const posts = await getData();

  return <BlogContainer posts={posts} />;
};

export default Blogs;

Create post:

const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const {
      content,
    } = formik.values;

    const success = await createPost(
     content
    ); //createPost is a function to create new post with try catch block, finally return true if no error
    if (success) {
      router.push("/blogs");
    }
  };
Statolatry answered 3/6, 2023 at 8:2 Comment(0)
U
10

For now, the solution that i found is by using combination of router.refresh & useTransition hook:

import { useRouter } from 'next/navigation';
import { useTransition } from 'react'

const Page = () => {
  const router = useRouter();
  const [isPending, startTransition] = useTransition();

  const onSubmit = () => {
    const url = '/blogs'

    startTransition(() => router.push(url));
    startTransition(() => router.refresh());
  }

  if (isPending) {
    return (
      <div>Loading...</div>
    )
  }

  return // Component
}

Source: Next.js Issue

Udelle answered 25/6, 2023 at 7:31 Comment(1)
Looks like they've taken this to a separate discussion here: github.com/vercel/next.js/discussions/54075Blepharitis
M
2

For those who have the same issue in Next 14, you can use revalidatePath from 'next/cache'. Please, note that it must be called on the server side:

'use server'

import { revalidatePath } from 'next/cache'

export default async function revalidate(path: string) {
  revalidatePath(path)
}

Then you can call this action and pass your path that you want to revalidate. In the example code the author provided this action must be called before router.push("/blogs"):

await revalidate("/blogs")
Mcroberts answered 17/6 at 13:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.