Menu

revalidatePath

revalidatePath により、特定のパスに対するオンデマンドでのキャッシュデータの無効化が可能になります。

使用方法

revalidatePath はServer Functionsおよび Route Handlers内で呼び出すことができます。

revalidatePath は Client Components内または Proxy内では呼び出せません。サーバー環境でのみ動作するためです。

補足:

  • Server Functions: UIを即座に更新します(影響を受けるパスを表示している場合)。現在のところ、以前にアクセスしたすべてのページは再度ナビゲートされたときにリフレッシュされます。この動作は一時的なもので、将来的には特定のパスにのみ適用されるように更新される予定です。
  • Route Handlers: パスを再検証用にマークします。再検証は指定されたパスへの次のアクセス時に実行されます。つまり、動的ルートセグメントで revalidatePath を呼び出しても、一度に多くの再検証が即座にトリガーされることはありません。無効化は次にパスがアクセスされたときにのみ発生します。

パラメータ

revalidatePath(path: string, type?: 'page' | 'layout'): void;
  • path: 再検証するデータに対応するルートパターン(例:/product/[slug])、または特定のURL(/product/123)。/page/layout を追加しないでください。代わりに type パラメータを使用してください。1024文字を超えてはいけません。この値は大文字と小文字を区別します。
  • type: (オプション)再検証するパスのタイプを変更する 'page' または 'layout' 文字列。path に動的セグメント(例:/product/[slug])が含まれている場合、このパラメータは必須です。path が特定のURL(/product/1)の場合は、type を省略してください。

単一ページをリフレッシュしたい場合は特定のURLを使用します。複数のURLをリフレッシュしたい場合はルートパターンに type を付けて使用します。

戻り値

revalidatePath は値を返しません。

無効化できるもの

pathパラメータはページ、レイアウト、またはroute handlersを指すことができます。

  • Pages: 特定のページを無効化します
  • Layouts: レイアウト(そのセグメントの layout.tsx)、その配下のすべてのネストされたレイアウト、およびその配下のすべてのページを無効化します
  • Route Handlers: route handler内でアクセスされたデータキャッシュエントリを無効化します。例えば revalidatePath("/api/data") は以下のGETハンドラーを無効化します。
app/api/data/route.ts
export async function GET() {
  const data = await fetch('https://api.vercel.app/blog', {
    cache: 'force-cache',
  })
 
  return Response.json(await data.json())
}

revalidateTag および updateTag との関係

revalidatePathrevalidateTag、およびupdateTagはそれぞれ異なる目的を持っています。

  • revalidatePath: 特定のページまたはレイアウトパスを無効化します
  • revalidateTag: 特定のタグでマークされたデータを古いものとしてマークします。そのタグを使用するすべてのページに適用されます
  • updateTag: 特定のタグを持つデータを期限切れにします。そのタグを使用するすべてのページに適用されます

revalidatePath を呼び出すと、次のアクセス時に指定されたパスのみが新しいデータを取得します。同じデータタグを使用する他のページは、特定のタグも再検証されるまで、キャッシュされたデータを提供し続けます。

// ページA: /blog
const posts = await fetch('https://api.vercel.app/blog', {
  next: { tags: ['posts'] },
})
 
// ページB: /dashboard
const recentPosts = await fetch('https://api.vercel.app/blog?limit=5', {
  next: { tags: ['posts'] },
})

revalidatePath('/blog') を呼び出した後:

  • ページA(/blog): 新しいデータを表示します(ページが再レンダリングされます)
  • ページB(/dashboard): 依然として古いデータを表示します(キャッシュタグ'posts'は無効化されていません)

revalidateTagupdateTag の違いについて詳しく学んでください。

再検証ユーティリティの構築

revalidatePathupdateTag は相補的なプリミティブであり、アプリケーション全体でデータの一貫性を確保するために、ユーティリティ関数内で一緒に使用されることがよくあります。

'use server'
 
import { revalidatePath, updateTag } from 'next/cache'
 
export async function updatePost() {
  await updatePostInDatabase()
 
  revalidatePath('/blog') // ブログページをリフレッシュします
  updateTag('posts') // 'posts' タグを使用するすべてのページをリフレッシュします
}

このパターンにより、特定のページと同じデータを使用する他のページの両方が一貫性を保つことが保証されます。

特定のURLの再検証

import { revalidatePath } from 'next/cache'
revalidatePath('/blog/post-1')

次のページアクセス時に、1つの特定のURLを再検証用に無効化します。

ページパスの再検証

import { revalidatePath } from 'next/cache'
revalidatePath('/blog/[slug]', 'page')
// またはルートグループを使用する場合
revalidatePath('/(main)/blog/[slug]', 'page')

提供されたページファイルにマッチするすべてのURLを次のページアクセス時に再検証用に無効化します。これは、特定のページより下のページを無効化しません。例えば、/blog/[slug]/blog/[slug]/[author] を無効化しません。

レイアウトパスの再検証

import { revalidatePath } from 'next/cache'
revalidatePath('/blog/[slug]', 'layout')
// またはルートグループを使用する場合
revalidatePath('/(main)/post/[slug]', 'layout')

提供されたレイアウトファイルにマッチするすべてのURLを次のページアクセス時に再検証用に無効化します。これにより、同じレイアウトを持つ下位のページが無効化され、次のアクセス時に再検証されます。例えば、上記の場合、/blog/[slug]/[another] も無効化され、次のアクセス時に再検証されます。

すべてのデータを再検証

import { revalidatePath } from 'next/cache'
 
revalidatePath('/', 'layout')

これはClient-side Router Cacheをパージし、次のページアクセス時の再検証のためにデータキャッシュを無効化します。

Server Function

app/actions.ts
TypeScript
'use server'
 
import { revalidatePath } from 'next/cache'
 
export default async function submit() {
  await submitForm()
  revalidatePath('/')
}

Route Handler

app/api/revalidate/route.ts
TypeScript
import { revalidatePath } from 'next/cache'
import type { NextRequest } from 'next/server'
 
export async function GET(request: NextRequest) {
  const path = request.nextUrl.searchParams.get('path')
 
  if (path) {
    revalidatePath(path)
    return Response.json({ revalidated: true, now: Date.now() })
  }
 
  return Response.json({
    revalidated: false,
    now: Date.now(),
    message: 'Missing path to revalidate',
  })
}