← Blog

Next.js 元資料未更新?這就是為什麼

您更新 generateMetadata,重新部署,當您分享連結時,舊標題或圖像仍然顯示。以下是如何判斷是快取層還是程式碼錯誤的方法。

不確定這是您的程式碼還是快取?

使用Proovd免費檢查。它準確顯示您的即時 URL 目前正在提供哪些元數據,獨立於任何平台自己的快取。

快速解答

  • 大多數情況是 Next.js 自己的資料快取或 CDN 快取提供過時的 HTML,而不是程式碼錯誤
  • 伺服器元件中的generateMetadata僅在其底層取得快取重新驗證時才重新執行
  • 其餘的通常是平台的快取(Facebook、LinkedIn等),而不是Next.js。在假設任一之前檢查兩者

可重複的例子

這看起來是正確的,但在內容更改後將繼續提供陳舊的元資料:

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的Data Cache快取的。如果 CMS 中的 post.titlepost.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. 加入顯式 revalidatecache: "no-store" 以在 generateMetadata 內獲取
  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. 新增了顯式重新驗證或快取:「no-store」以在 generateMetadata 內獲取
  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 中目前的內容,獨立於任何平台的快取。