generateMetadata
您可以使用 metadata
物件或 generateMetadata
函數來定義元數據。
metadata
物件
要定義靜態元數據,可以從 layout.js
或 page.js
檔案匯出一個 Metadata
物件。
完整支援的選項清單請參閱 元數據欄位。
generateMetadata
函數
依賴於動態資訊的元數據,例如當前路由參數、外部數據或父區段的 metadata
,可以透過匯出一個返回 Metadata
物件 的 generateMetadata
函數來設定。
須知事項:
- 元數據可以添加到
layout.js
和page.js
檔案中。- Next.js 會自動解析元數據,並為頁面建立相關的
<head>
標籤。metadata
物件和generateMetadata
函數匯出僅在伺服器元件 (Server Components) 中支援。- 您不能從同一個路由區段同時匯出
metadata
物件和generateMetadata
函數。generateMetadata
中的fetch
請求會自動記憶化 (memoized),以便在generateMetadata
、generateStaticParams
、Layouts、Pages 和 Server Components 之間共享相同數據。- 如果無法使用
fetch
,可以使用 React 的cache
函數。- 基於檔案的元數據 具有更高優先級,會覆蓋
metadata
物件和generateMetadata
函數。
參考
參數
generateMetadata
函數接受以下參數:
-
props
- 包含當前路由參數的物件:-
params
- 包含從根區段到呼叫generateMetadata
的區段的動態路由參數物件。例如:路由 URL params
app/shop/[slug]/page.js
/shop/1
{ slug: '1' }
app/shop/[tag]/[item]/page.js
/shop/1/2
{ tag: '1', item: '2' }
app/shop/[...slug]/page.js
/shop/1/2
{ slug: ['1', '2'] }
-
searchParams
- 包含當前 URL 的查詢參數 (search params) 的物件。例如:URL searchParams
/shop?a=1
{ a: '1' }
/shop?a=1&b=2
{ a: '1', b: '2' }
/shop?a=1&a=2
{ a: ['1', '2'] }
-
-
parent
- 父路由區段解析後的元數據的 Promise。
返回值
generateMetadata
應返回包含一個或多個元數據欄位的 Metadata
物件。
須知事項:
- 如果元數據不依賴於運行時資訊,應使用靜態的
metadata
物件 而非generateMetadata
來定義。fetch
請求會自動記憶化 (memoized),以便在generateMetadata
、generateStaticParams
、Layouts、Pages 和 Server Components 之間共享相同數據。如果無法使用fetch
,可以使用 React 的cache
函數。searchParams
僅在page.js
區段中可用。- Next.js 的
redirect()
和notFound()
方法也可以在generateMetadata
中使用。
元數據欄位
支援以下欄位:
title
title
屬性用於設定文件的標題。可以定義為簡單的字串或可選的模板物件。
字串
default
title.default
可用於為未定義 title
的子路由區段提供後備標題。
template
title.template
可用於為子路由區段中定義的 titles
添加前綴或後綴。
須知事項:
title.template
應用於子路由區段,而非定義它的區段。這意味著:
- 添加
title.template
時,必須提供title.default
。layout.js
中定義的title.template
不會應用於同一路由區段的page.js
中定義的title
。page.js
中定義的title.template
無效,因為頁面始終是路由的終止區段(它沒有任何子路由區段)。如果路由未定義
title
或title.default
,則title.template
無效。
absolute
title.absolute
可用於提供忽略父區段中設定的 title.template
的標題。
須知事項:
layout.js
title
(字串) 和title.default
為未定義自己title
的子區段定義預設標題。如果存在,它將擴展來自最近父區段的title.template
。title.absolute
為子區段定義預設標題。它忽略來自父區段的title.template
。title.template
為子區段定義新的標題模板。
page.js
- 如果頁面未定義自己的標題,將使用最近父區段的解析標題。
title
(字串) 定義路由的標題。如果存在,它將擴展來自最近父區段的title.template
。title.absolute
定義路由標題。它忽略來自父區段的title.template
。title.template
在page.js
中無效,因為頁面始終是路由的終止區段。
description
其他欄位
metadataBase
metadataBase
是一個便利選項,用於為需要完整 URL 的 metadata
欄位設定基礎 URL 前綴。
metadataBase
允許當前路由區段及以下定義的基於 URL 的metadata
欄位使用相對路徑,而非原本需要的絕對 URL。- 欄位的相對路徑將與
metadataBase
組合形成完整的 URL。
須知事項:
metadataBase
通常設定在根目錄的app/layout.js
中,以應用於所有路由的基於 URL 的metadata
欄位。- 所有需要絕對 URL 的基於 URL 的
metadata
欄位都可以透過metadataBase
選項進行設定。metadataBase
可以包含子網域,例如https://app.acme.com
或基礎路徑,例如https://acme.com/start/from/here
。- 如果
metadata
欄位提供了絕對 URL,則metadataBase
將被忽略。- 在未設定
metadataBase
的情況下在基於 URL 的metadata
欄位中使用相對路徑會導致建置錯誤。- Next.js 會標準化
metadataBase
(例如https://acme.com/
)和相對欄位(例如/path
)之間的重複斜線為單一斜線(例如https://acme.com/path
)。
URL 組合
URL 組合優先考慮開發者意圖而非預設的目錄遍歷語義。
metadataBase
和metadata
欄位之間的尾部斜線會被標準化。metadata
欄位中的「絕對」路徑(通常會替換整個 URL 路徑)會被視為「相對」路徑(從metadataBase
的末尾開始)。
例如,給定以下 metadataBase
:
任何繼承上述 metadataBase
並設定自己值的 metadata
欄位將按以下方式解析:
metadata 欄位 | 解析後的 URL |
---|---|
/ | https://acme.com |
./ | https://acme.com |
payments | https://acme.com/payments |
/payments | https://acme.com/payments |
./payments | https://acme.com/payments |
../payments | https://acme.com/payments |
https://beta.acme.com/payments | https://beta.acme.com/payments |
openGraph
須知事項:
- 對於 Open Graph 圖片,使用 檔案式 Metadata API 可能更方便。檔案式 API 會自動為你生成正確的中繼資料,而不需要手動同步設定檔與實際檔案。
robots
icons
須知事項:建議盡可能使用 檔案式 Metadata API 來設定圖示。檔案式 API 會自動生成正確的中繼資料,而不需要手動同步設定檔與實際檔案。
須知事項:Chromium 版本的 Microsoft Edge 已不再支援
msapplication-*
元標籤,因此不再需要這些標籤。
themeColor
已棄用:從 Next.js 14 開始,
metadata
中的themeColor
選項已被棄用。請改用viewport
設定。
colorScheme
已棄用:從 Next.js 14 開始,
metadata
中的colorScheme
選項已被棄用。請改用viewport
設定。
manifest
網頁應用程式清單 (Web Application Manifest),定義於 網頁應用程式清單規範。
twitter
Twitter 規範(令人驚訝地)不僅僅用於 X(原 Twitter)。
了解更多關於 Twitter 卡片標記參考。
viewport
已棄用:從 Next.js 14 開始,
metadata
中的viewport
選項已被棄用。請改用viewport
設定。
verification
appleWebApp
alternates
appLinks
archives
描述具有歷史價值的記錄、文件或其他材料的集合(來源)。
assets
bookmarks
category
facebook
你可以將 Facebook 應用程式或 Facebook 帳戶連接到你的網頁,以使用某些 Facebook 社交插件 Facebook 文件
須知事項:你可以指定 appId 或 admins,但不能同時指定兩者。
如果你想生成多個 fb:admins 元標籤,可以使用陣列值。
pinterest
你可以在網頁上啟用或停用 Pinterest Rich Pins。
other
所有中繼資料選項都應使用內建支援來涵蓋。然而,可能會有特定於你的網站的自訂中繼資料標籤,或是剛發布的全新中繼資料標籤。你可以使用 other
選項來渲染任何自訂中繼資料標籤。
如果你想生成多個相同鍵的元標籤,可以使用陣列值。
不支援的中繼資料
以下中繼資料類型目前沒有內建支援。不過,仍然可以在佈局或頁面本身中渲染它們。
類型
你可以使用 Metadata
類型為你的元資料添加類型安全。如果你在 IDE 中使用內建的 TypeScript 插件,則無需手動添加類型,但你仍然可以明確添加它。
metadata
物件
generateMetadata
函式
一般函式
非同步函式
帶有區段屬性
帶有父元資料
JavaScript 專案
對於 JavaScript 專案,你可以使用 JSDoc 來添加類型安全。
元資料 | 建議 |
---|---|
<meta http-equiv="..."> | 使用適當的 HTTP 標頭,透過 redirect() 、中介軟體 (Middleware) 或 安全標頭 (Security Headers) |
<base> | 在佈局 (layout) 或頁面 (page) 本身渲染該標籤。 |
<noscript> | 在佈局或頁面本身渲染該標籤。 |
<style> | 了解更多關於 Next.js 中的樣式設定。 |
<script> | 了解更多關於 使用腳本。 |
<link rel="stylesheet" /> | 直接在佈局或頁面本身 import 樣式表。 |
<link rel="preload /> | 使用 ReactDOM preload 方法 |
<link rel="preconnect" /> | 使用 ReactDOM preconnect 方法 |
<link rel="dns-prefetch" /> | 使用 ReactDOM prefetchDNS 方法 |
資源提示
<link>
元素有許多 rel
關鍵字,可用於向瀏覽器提示可能需要外部資源。瀏覽器根據這些關鍵字應用預載優化。
雖然元資料 API 不直接支援這些提示,但你可以使用新的 ReactDOM
方法 安全地將它們插入到文件的 <head>
中。
<link rel="preload">
在頁面渲染 (瀏覽器) 生命週期的早期開始載入資源。MDN 文件。
<link rel="preconnect">
預先初始化與來源的連接。MDN 文件。
<link rel="dns-prefetch">
在資源被請求之前嘗試解析域名。MDN 文件。
須知:
- 這些方法目前僅在客戶端元件 (Client Components) 中支援,這些元件在初始頁面載入時仍會進行伺服器端渲染 (SSR)。
- Next.js 內建功能如
next/font
、next/image
和next/script
會自動處理相關的資源提示。
行為
預設欄位
有兩個預設的 meta
標籤總是會被添加,即使路由沒有定義元資料:
- meta charset 標籤 設定網站的字符編碼。
- meta viewport 標籤 設定網站的視口寬度和縮放比例,以適應不同裝置。
須知:你可以覆蓋預設的
viewport
meta 標籤。
串流元資料
generateMetadata
返回的元資料會被串流到客戶端。這使得 Next.js 能夠在元資料解析後立即將其注入 HTML。
由於頁面元資料主要針對機器人和爬蟲,Next.js 會為能夠執行 JavaScript 並檢查完整頁面 DOM 的機器人(如 Googlebot
)串流元資料。然而,對於 HTML 受限 的機器人(如 Twitterbot
),元資料會繼續阻擋頁面渲染,因為這些機器人在爬取時無法執行 JavaScript。
Next.js 會自動檢測傳入請求的使用者代理,以決定是提供串流元資料還是回退到阻擋元資料。
如果需要自訂此列表,你可以使用 next.config.js
中的 htmlLimitedBots
選項手動定義它們。Next.js 會確保符合此正則表達式的使用者代理在請求你的網頁時收到阻擋元資料。
指定 htmlLimitedBots
配置將覆蓋 Next.js 的預設列表,讓你完全控制哪些使用者代理應選擇此行為。這是進階行為,預設值在大多數情況下已足夠。
順序
元資料按順序評估,從根區段開始,一直到最接近最終 page.js
區段的區段。例如:
app/layout.tsx
(根佈局)app/blog/layout.tsx
(嵌套的部落格佈局)app/blog/[slug]/page.tsx
(部落格頁面)
合併
遵循評估順序,從同一路由的多個區段導出的元資料物件會 淺層合併 在一起,形成路由的最終元資料輸出。重複的鍵會根據它們的順序 替換。
這意味著嵌套欄位(如 openGraph
和 robots
)在早期區段中定義的元資料會被最後一個定義它們的區段 覆蓋。
覆蓋欄位
在上面的例子中:
app/layout.js
中的title
被app/blog/page.js
中的title
替換。app/layout.js
中的所有openGraph
欄位在app/blog/page.js
中被 替換,因為app/blog/page.js
設定了openGraph
元資料。注意缺少openGraph.description
。
如果你想在區段之間共享一些嵌套欄位,同時覆蓋其他欄位,可以將它們提取到單獨的變數中:
在上面的例子中,OG 圖片在 app/layout.js
和 app/about/page.js
之間共享,而標題則不同。
繼承欄位
注意
app/layout.js
中的title
被app/about/page.js
中的title
替換。app/layout.js
中的所有openGraph
欄位在app/about/page.js
中被 繼承,因為app/about/page.js
沒有設定openGraph
元資料。
版本歷史
版本 | 變更 |
---|---|
v15.2.0 | 引入對 generateMetadata 的串流支援。 |
v13.2.0 | viewport 、themeColor 和 colorScheme 被棄用,轉而支援 viewport 配置。 |
v13.2.0 | 引入 metadata 和 generateMetadata 。 |