#Revalidate cache after form submitted client-side

1 messages · Page 1 of 1 (latest)

slender mountain
#

I'm using Next.js to host my front end. I have an API which is not on the same Next.js server. When I submit a form from my Next.js app (client-side), I want to use revalidateTag to refresh the cache for a given fetch tag. How do I do this?

stoic yachtBOT
#

Hi @slender mountain. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

To revalidate the cache after a form submission on the client-side in Next.js, you can use the revalidateTag function. This function allows you to purge cached data on-demand for a specific cache tag. Here's how you can do it:

  1. When using fetch, you have the option to tag cache entries with one or more tags. For example, you can set a tag when fetching data:
// Cache data with a tag
fetch(`<https://...`,> { next: { tags: ['a', 'b', 'c'] } })
  1. Then, you can call revalidateTag to purge the cache entries associated with that tag. This can be done in a Server Action or Route Handler. For example:
// Revalidate entries with a specific tag
revalidateTag('a')

Please note that revalidateTag only invalidates the cache when the path is next visited. This means calling revalidateTag with a dynamic route segment will not immediately trigger many revalidations at once. The invalidation only happens when the path is next visited.

Here's an example of how you can use revalidateTag in a Server Action:

'use server'
 
import { revalidateTag } from 'next/cache'
 
export default async function submit() {
 await addPost()
 revalidateTag('posts')
}

And here's an example of how you can use revalidateTag in a Route Handler:

import { NextRequest } from 'next/server'
import { revalidateTag } from 'next/cache'
 
export async function GET(request: NextRequest) {
 const tag = request.nextUrl.searchParams.get('tag')
 revalidateTag(tag)
 return Response.json({ revalidated: true, now: Date.now() })
}

Please note that revalidateTag is available in both Node.js and Edge runtimes.

#

@slender mountain kapa.ai is still learning and improving, please let us know how it did by reacting below

slender mountain
#

@stoic yacht ok thanks, your documentation in clear on that. However I'm handling form submission in a page with ' use client'. And I want to call revalidateTag when the form is submitted. However, I'm getting the following error: Invariant: static generation store missing in revalidateTag

stoic yachtBOT
#

Let me check the knowledge base for you. One moment! :books:

#

The error you're encountering, Invariant: static generation store missing in revalidateTag, typically occurs when you're trying to call revalidateTag on the client-side. The revalidateTag function is designed to be used on the server-side, not on the client-side.

In Next.js, you can use revalidateTag in two places depending on what you're trying to achieve:

  1. Route Handlers (https://nextjs.org/docs/app/building-your-application/routing/route-handlers) - to revalidate data in response to a third-party event (e.g., webhook). This will not invalidate the Router Cache immediately as the Router Handler isn't tied to a specific route.

  2. Server Actions (https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations) - to revalidate data after a user action (e.g., form submission). This will invalidate the Router Cache for the associated route.

If you're handling form submissions on the client-side, you might want to consider using startTransition or useTransition to ensure that revalidation and navigation happen in one step. This will ensure that the new data is available for the UI when the navigation happens. Depending on your caching configuration, your route handler/API route might need to call revalidatePath or revalidateTag to clear any other cache than the Router Cache.

Here's an example:

"use client";

import { startTransition, useTransition } from "react";
import { action } from "./action";

export const MyForm = () => {
  const [result, formAction] = useTransition(action, undefined);

  const handleSubmit = (event) => {
    event.preventDefault();
    startTransition(() => {
      formAction();
    });
  };
#

return (
<form onSubmit={handleSubmit}>
<input type="text" name="name" placeholder="Name" autoComplete="off" />
<button type="submit">Submit</button>
<p>Response: {result}</p>
</form>
);
};


In this example, `startTransition` is used to start a transition that updates the state (in this case, the form submission) and revalidates the cache.

Remember, the Router Cache is cleared by `router.refresh`, the other cache layers have to be revalidated via the Server-side functions `revalidatePath` or `revalidateTag` as that can conceptually not happen on the client (**source** (<https://github.com/vercel/next.js/issues/56500>)).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------