TOOLS BOX/ガイド/revalidateTag
API / Option

revalidateTag

fetch に付けたタグを指定して、タグ単位でキャッシュを即時無効化する関数。複数ページにまたがるデータ更新に有効。

nextjscacherevalidatetagserver-action
所属:next/cache

代表的な値 / 使い方

  • revalidateTag('posts')
  • revalidateTag(`post-${id}`)
  • revalidateTag('cms-content')

注意点 / Pitfalls

  • ·fetch 側に next: { tags: [...] } を設定していないと revalidateTag を呼んでも何も無効化されない
  • ·Server Action・Route Handler の中でのみ呼べる(クライアントコンポーネントでは使えない)
  • ·タグの粒度が荒すぎると(例: 'all')関係ないページまで再検証される
  • ·タグの粒度が細かすぎると(例: 全レコードに個別タグ)呼び忘れが増え管理が複雑になる

一緒に使う項目

補足

revalidatePath はパス単位の無効化、revalidateTag はデータ種別(タグ)単位の無効化。1 件の投稿更新が一覧・詳細・関連ページの複数ルートに影響する場合、各パスを列挙するより revalidateTag の方がシンプルになりやすい。

何をする関数か

revalidateTagfetch リクエストに付けたタグを指定し、そのタグを持つすべてのキャッシュを即時無効化する関数です。Server Action や Route Handler でデータを更新したあとに呼びます。

"use server";
import { revalidateTag } from "next/cache";

export async function updatePost(id: string) {
  await db.post.update({ where: { id }, data: { ... } });
  revalidateTag("posts");          // "posts" タグを持つ全キャッシュを無効化
  revalidateTag(`post-${id}`);    // 特定投稿のキャッシュだけ無効化
}

タグ設計が前提になる

revalidateTag が有効になるには、fetch 側で next: { tags: [...] } を設定しておく必要があります。タグなしの fetchrevalidateTag の対象外です。

// データ取得側: タグを付けておく
const posts = await fetch("/api/posts", {
  next: { tags: ["posts"] },
});

const post = await fetch(`/api/posts/${id}`, {
  next: { tags: ["posts", `post-${id}`] },
});
// 更新側: タグで無効化
revalidateTag("posts");       // 一覧系をまとめて無効化
revalidateTag(`post-${id}`); // 特定投稿のみ無効化

revalidatePath との使い分け

revalidatePathrevalidateTag
無効化の単位URL パスデータのタグ
複数ページまたぎパスを個別に列挙タグ 1 つで一括
前提条件特になしfetch 側のタグ設計が必要
向くケース更新対象ページが明確で少ない1 件の更新が複数ルートに影響する

1 件の投稿更新が一覧・詳細・カテゴリページなど複数ルートに影響する場合、revalidatePath では各パスを列挙する必要があります。revalidateTag なら "posts" タグ 1 つで一括無効化できます。

よくあるつまずき

タグを付けていない

revalidateTag("posts") を呼んでも、fetch 側に tags: ["posts"] が付いていないと何も無効化されません。タグは取得側と更新側の両方で設計する必要があります。

タグの粒度が荒すぎる

// ❌ 何でも "all" にすると関係ないページまで再検証される
revalidateTag("all");

// ✅ データ種別でタグを分ける
revalidateTag("posts");
revalidateTag("users");

タグの粒度が細かすぎる

レコードごとに post-1, post-2, ... と個別タグを付けると、更新時に revalidateTag の呼び出しが増えて管理が複雑になります。一覧と詳細で共通のタグ("posts")を持ちつつ、詳細専用タグ(`post-${id}`)を追加するハイブリッド設計が実用的です。

注意点

  • Server Action・Route Handler の中でのみ呼べる(クライアントコンポーネントでは使えない)
  • fetch を使わない Prisma 直接クエリなどには tags オプションが存在しない。そのような場合は revalidatePath を使う
  • タグ名は文字列の一致で管理されるため、タイポに気づきにくい。定数として管理すると安全
// タグ名を定数管理する例
export const CACHE_TAGS = {
  posts: "posts",
  post: (id: string) => `post-${id}`,
} as const;

// 取得側
fetch("/api/posts", { next: { tags: [CACHE_TAGS.posts] } });

// 更新側
revalidateTag(CACHE_TAGS.posts);

revalidatePath との違いやキャッシュ設計の全体像は → Next.js キャッシュ設計

関連ドキュメント

関連サンプル

同じテーマや技術スタックを使った実装例