← Blog

Next.js メタデータが更新されませんか?その理由は次のとおりです

generateMetadata を更新して再デプロイしても、リンクを共有すると古いタイトルまたは画像が引き続き表示されます。キャッシュ層なのかコードの間違いなのかを判断する方法は次のとおりです。

コードなのかキャッシュなのかわかりませんか?

Proovd で無料でチェックしてください。プラットフォーム独自のキャッシュに関係なく、ライブ URL が現在どのようなメタデータを提供しているかを正確に表示します。

簡単な回答

  • ほとんどのケースは、コードのバグではなく、Next.js 独自のデータ キャッシュ、または古い HTML を提供する CDN キャッシュです。
  • サーバー コンポーネント内の generateMetadata は、基礎となるフェッチ キャッシュが再検証された場合にのみ再実行されます。
  • 残りは通常、Next.js ではなく、プラットフォームのキャッシュ (Facebook、LinkedIn など) です。どちらかを推測する前に両方を確認してください

再現可能な例

これは正しいように見えますが、コンテンツが変更された後も古いメタデータが提供され続けます。

export async function generateMetadata({ params }) {
  const post = await fetch(`https://api.example.com/posts/${params.slug}`).then(r => r.json());

  return {
    title: post.title,
    openGraph: {
      images: [post.image],
    },
  };
}

ここでの fetch 呼び出しは、デフォルトで Next.js のデータ キャッシュによってキャッシュされます。 CMS で post.title または post.image が変更された場合、この関数はキャッシュが再検証されるまで新しい値を認識しません。明確な戦略がない場合、次の完全なビルドまでは続かない可能性があります。

メタデータが更新されない理由

基礎となるフェッチはキャッシュされます

デフォルトでは、generateMetadata 内の fetch() は App Router に無期限にキャッシュされます。明示的な再検証ウィンドウを設定して修正します。

const post = await fetch(url, { next: { revalidate: 60 } }).then(r => r.json());

または、そのリクエストのキャッシュを完全にオプトアウトします。

const post = await fetch(url, { cache: "no-store" }).then(r => r.json());

ルートは静的に生成されます

再検証が構成されていない状態でルートが generateStaticParams を使用する場合、メタデータを含むルート全体がビルド時にベイクインされます。ページ レベルで export const revalidate = 3600; を追加すると、定期的な再生成が強制されます。

CDN またはエッジ キャッシュが古い HTML を提供しています

ビルドが正しい場合でも、アプリの前にある Vercel の Edge Network、Cloudflare、または別の CDN が、修正より前のキャッシュされた HTML 応答を提供する可能性があります。応答ヘッダーを確認します。

curl -I https://yoursite.com/blog/post-slug

x-vercel-cache: HIT または同様の CDN ヘッダーを探します。 HIT は、最新のデプロイではなく、キャッシュされたコピーを参照していることを意味します。

opengraph-image.ts が新しいデータを取得していません

ファイルベースの opengraph-image.ts 規則を使用している場合、Next.js はデフォルトでビルド時に静的イメージを生成します。その内部の動的コンテンツには、他のサーバー コンポーネントと同じキャッシュ ルールが適用されるため、最新の状態を維持する必要がある場合は、明示的な再検証を追加してください。

実際にはそれはあなたのものではなくプラットフォームのキャッシュです

最も一般的な誤報。 Facebook、LinkedIn、または Slack が数日前にキャッシュしたプレビューを表示している間、アプリは完全に新しいメタデータを提供できます。 Next.js コードに触れる前に、サーバーが送信している内容を確認してください。すべてのプラットフォームで OG キャッシュをクリアするためのガイドを参照してください

ステップバイステップの修正ガイド

  1. curl -s https://yoursite.com/page | を実行します。 grep -i "og:" サーバーが実際に送信したものを確認します
  2. curl -I https://yoursite.com/page で CDN キャッシュ HIT ヘッダーを確認します
  3. generateMetadata 内のフェッチに明示的な revalidate または cache: "no-store" を追加します。
  4. 古いビルド キャッシュを除外するために新規デプロイを強制する
  5. Proovd でライブ結果を確認します

Next.js 対他のフレームワーク

Framework Common cause Fix pattern
Next.js (App Router) Cached fetch inside generateMetadata, or static build with no ISR revalidate option or cache: "no-store"
Astro Client-only meta tag injection instead of static frontmatter/SSR Move tags into the page's static output
SvelteKit Meta tags set only client-side, not in the server load function Load meta values server-side, pass to the head

クイックフィックスチェックリスト

  1. 生の HTML 出力に正しいタグが含まれていることを確認しました (ブラウザ DOM だけではありません)。
  2. 明示的な再検証またはキャッシュを追加しました: generateMetadata 内でフェッチするための「no-store」
  3. CDN/エッジ キャッシュ ヘッダーで古い HIT を確認しました
  4. ルートがISR なしで完全に静的であるかどうかを確認しました
  5. ソーシャルプラットフォーム自体のキャッシュが本当の原因である可能性を排除
  6. Proovd で最終的なライブ出力を確認しました

よくある質問

ブラウザでは og:image が更新されるのに、Facebook や LinkedIn では更新されないのはなぜですか?

あなたの Next.js アプリはすでに正しいタグを提供している可能性があります。プラットフォームは、修正前にキャッシュされたコピーを表示しています。さらにコードを変更するのではなく、そのプラットフォーム独自のキャッシュ更新ツールを使用してください。

revalidate: 0 はキャッシュを完全に無効にしますか?

revalidate: 0 を設定すると、cache: "no-store" と同様に、すべてのリクエストでそのフェッチの動的レンダリングが効果的に強制されます。キャッシュによるパフォーマンス上の利点が失われるため、使用は慎重に行ってください。

あなたの Next.js アプリが実際に何を提供しているかを確認してください

Proovd を使用してライブメタデータを無料で確認してください。プラットフォームのキャッシュに関係なく、HTML の現在の内容を正確に表示します。