コンテンツにスキップ

revalidatePath

revalidatePath は、特定のパスのキャッシュされたデータをオンデマンドで無効化できます。

使用方法

revalidatePath はサーバー関数およびルートハンドラーで呼び出すことができます。

revalidatePath はクライアントコンポーネントまたはプロキシでは呼び出せません。サーバー環境でのみ機能します。

知っておくと良いこと:

  • サーバー関数: UIを即座に更新します(影響を受けるパスを表示している場合)。現在、これは、過去に訪問したすべてのページが再度ナビゲートされたときにリフレッシュされる原因にもなります。この動作は一時的なものであり、将来的には特定のパスにのみ適用されるように更新されます。
  • ルートハンドラー: パスを再検証のためにマークします。再検証は、指定されたパスへの次の訪問時に行われます。これは、動的なルートセグメントでrevalidatePathを呼び出しても、一度に多くの再検証が即座にトリガーされるわけではないことを意味します。無効化は、パスが次に訪問されたときにのみ発生します。

Parameters

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を使用します。ルートパターンとtypeを使用して、複数のURLをリフレッシュします。

戻り値

revalidatePath は値を返しません。

無効化できるもの

pathパラメータは、ページ、レイアウト、またはルートハンドラーを指すことができます

  • ページ: 特定のページを無効化します
  • レイアウト: レイアウト(そのセグメントにあるlayout.tsx)、その下のすべてのネストされたレイアウト、およびそれらの下のすべてのページを無効化します
  • ルートハンドラー: ルートハンドラー内でアクセスされるデータキャッシュエントリを無効化します。例えば、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を呼び出した後、次に訪問したときに指定されたパスのみが新しいデータを取得します。同じデータタグを使用する他のページは、それらの特定のタグが再検証されるまで、引き続き古いデータを配信します

// Page A: /blog
const posts = await fetch('https://api.vercel.app/blog', {
  next: { tags: ['posts'] },
})
 
// Page 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') // Refresh the blog page
  updateTag('posts') // Refresh all pages using 'posts' tag
}

このパターンにより、特定のページと、同じデータタグを使用する他のすべてのページが整合性を保つことが保証されます。

特定のURLの無効化

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

これにより、次のページ訪問時に1つの特定のURLが無効化され、再検証されるようになります。

ページパスの無効化

import { revalidatePath } from 'next/cache'
revalidatePath('/blog/[slug]', 'page')
// or with route groups
revalidatePath('/(main)/blog/[slug]', 'page')

これにより、提供されたpageファイルに一致するURLが次のページ訪問時に無効化され、再検証されるようになります。これは、その特定のページの下にあるページを無効化するわけではありません。例えば、/blog/[slug]/blog/[slug]/[author]を無効化しません。

レイアウトパスの無効化

import { revalidatePath } from 'next/cache'
revalidatePath('/blog/[slug]', 'layout')
// or with route groups
revalidatePath('/(main)/post/[slug]', 'layout')

これにより、提供されたlayoutファイルに一致するURLが次のページ訪問時に無効化され、再検証されるようになります。これにより、同じレイアウトを持つその下のページも無効化され、次回の訪問時に再検証されるようになります。例えば、上記のケースでは、/blog/[slug]/[another]も無効化され、次回の訪問時に再検証されます。

すべてのデータの無効化

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

これにより、クライアントサイドルーターキャッシュがパージされ、次のページ訪問時にデータキャッシュが無効化され、再検証されるようになります。

サーバー関数

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

ルートハンドラー

app/api/revalidate/route.ts
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',
  })
}