The Problem:
In a NextJS 13 application, the user list page is not being updated after a user is deleted. The delete user button is making an API call to delete the user, but the user list page (fetched using an external API) is not being refetched after the deletion. The goal is to understand why the user list page is not being refreshed and to find a solution to ensure that the page is updated after a user is deleted.
The Solutions:
Solution 1: Execute revalidate from a route handler or using server actions
The problem was that you were trying to execute the revalidate
directly from a Client Component
, which is not possible. To execute a revalidatePath
/ revalidateTag
from a Client Component
, you have two options:
Option 1: Request a route handler
- Create a route handler for the page where you want to perform the revalidation.
- In the route handler, call
revalidatePath
orrevalidateTag
.
For example, if you want to revalidate the /users
page after deleting a user, you could create the following route handler:
export async function handleUsers(req, res) {
// Revalidate the `/users` page
await revalidatePath(req, res, '/users')
// Redirect the user back to the `/users` page
res.redirect('/users')
}
Option 2: Use server actions
- Create a server action for the function you want to execute on the server.
- Call the server action from your client component.
For example, you could create the following server action to delete a user:
export async function deleteUser(req, res) {
// Get the user ID from the request body
const id = req.body.id
// Delete the user from the database
await User.deleteById(id)
// Revalidate the `/users` page
await revalidateTag(req, res, 'users')
// Send a success response
res.status(200).end()
}
And then you could call the server action from your client component like this:
const deleteUser = async (id) => {
// Call the server action to delete the user
await fetch('/api/delete-user', {
method: 'POST',
body: JSON.stringify({ id }),
})
// Redirect the user back to the `/users` page
router.push('/users')
}
Both of these options will allow you to execute a revalidate
from a Client Component
.
Solution 2: Using revalidateTag
The issue is that the `getUsers` function is fetching data from an external API and caching the results. When a user is deleted, the cached data is still being used, so the users list is not being updated. To fix this, you can use the `revalidateTag` function to invalidate the cache for the `users` tag whenever a user is deleted.
const deleteUserCallback = async (id: string) => {
deleteUser(id)
.then(() => {
revalidateTag("users") // Invalidate the cache for the "users" tag
router.push("/users")
})
}
This will ensure that the `getUsers` function will fetch fresh data from the API the next time it is called, and the users list will be updated.
Q&A
How to revalidate the cache when a user is created / updated / deleted?
Invalidate the cache using revalidatePath
or revalidateTag
, or disable caching for the getUsers
request.
How to fix the error: Error: Invariant: static generation store missing in revalidateTag users
?
This might be a bug on Vercel’s side, see the GitHub issue for more information.
Video Explanation:
The following video, titled "NextJS 13 Tutorial - Routing, Data Fetching, Server Components ...", provides additional insights and in-depth exploration related to the topics discussed in this post.
NextJS 13 came with a lot of new changes, so I wanted to make this video explaining what is up with the new update.
The following video, titled "NextJS 13 Tutorial - Routing, Data Fetching, Server Components ...", provides additional insights and in-depth exploration related to the topics discussed in this post.
NextJS 13 came with a lot of new changes, so I wanted to make this video explaining what is up with the new update.