如何添加元數據與建立 OG 圖片

Metadata API 可用於定義應用程式元數據以提升 SEO 和網頁分享性,包含以下功能:

  1. 靜態 metadata 物件
  2. 動態 generateMetadata 函式
  3. 特殊檔案慣例,可用於添加靜態或動態生成的網站圖示 (favicons)OG 圖片

使用上述所有選項時,Next.js 會自動為您的頁面生成相關的 <head> 標籤,您可以在瀏覽器的開發者工具中檢查這些標籤。

預設欄位

有兩個預設的 meta 標籤會始終添加,即使路由未定義元數據:

<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

其他元數據欄位可以透過 Metadata 物件(用於靜態元數據)或 generateMetadata 函式(用於生成的元數據)來定義。

靜態元數據

要定義靜態元數據,請從靜態的 layout.jspage.js 檔案中匯出一個 Metadata 物件。例如,為部落格路由添加標題和描述:

import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: '我的部落格',
  description: '...',
}

export default function Page() {}
export const metadata = {
  title: '我的部落格',
  description: '...',
}

export default function Page() {}

您可以在 generateMetadata 文件 中查看所有可用選項的完整列表。

生成元數據

您可以使用 generateMetadata 函式來 fetch 依賴於數據的元數據。例如,獲取特定部落格文章的標題和描述:

import type { Metadata, ResolvingMetadata } from 'next'

type Props = {
  params: Promise<{ slug: string }>
  searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}

export async function generateMetadata(
  { params, searchParams }: Props,
  parent: ResolvingMetadata
): Promise<Metadata> {
  const slug = (await params).slug

  // 獲取文章資訊
  const post = await fetch(`https://api.vercel.app/blog/${slug}`).then((res) =>
    res.json()
  )

  return {
    title: post.title,
    description: post.description,
  }
}

export default function Page({ params, searchParams }: Props) {}

在幕後,Next.js 會將元數據與 UI 分開串流,並在元數據解析完成後立即將其注入 HTML。

記憶化數據請求

在某些情況下,您可能需要為元數據和頁面本身獲取相同的數據。為了避免重複請求,您可以使用 React 的 cache 函式 來記憶返回值,僅獲取數據一次。例如,同時為元數據和頁面獲取部落格文章資訊:

import { cache } from 'react'
import { db } from '@/app/lib/db'

// getPost 會被使用兩次,但只執行一次
export const getPost = cache(async (slug: string) => {
  const res = await db.query.posts.findFirst({ where: eq(posts.slug, slug) })
  return res
})

基於檔案的元數據

以下特殊檔案可用於元數據:

您可以使用這些檔案來設定靜態元數據,也可以透過程式碼動態生成這些檔案。

網站圖示 (Favicons)

Favicons 是代表您網站在書籤和搜尋結果中的小圖示。要為應用程式添加 favicon,請建立一個 favicon.ico 並將其添加到應用程式資料夾的根目錄。

應用程式資料夾中的 Favicon 特殊檔案,與同層的 layout 和 page 檔案並列

您也可以使用程式碼動態生成 favicon。詳情請參閱 favicon 文件

靜態 Open Graph 圖片

Open Graph (OG) 圖片是代表您網站在社交媒體上的圖片。要為應用程式添加靜態 OG 圖片,請在應用程式資料夾的根目錄建立一個 opengraph-image.png 檔案。

應用程式資料夾中的 OG 圖片特殊檔案,與同層的 layout 和 page 檔案並列

您也可以透過在資料夾結構中更深層的位置建立 opengraph-image.png 來為特定路由添加 OG 圖片。例如,要為 /blog 路由建立專用的 OG 圖片,請在 blog 資料夾內添加一個 opengraph-image.jpg 檔案。

blog 資料夾內的 OG 圖片特殊檔案

更具體的圖片將優先於資料夾結構中上層的任何 OG 圖片。

其他圖片格式如 jpegpngwebp 也受支援。詳情請參閱 Open Graph 圖片文件

動態生成 Open Graph 圖片

ImageResponse 建構函式 允許您使用 JSX 和 CSS 生成動態圖片。這對於依賴數據的 OG 圖片非常有用。

例如,要為每篇部落格文章生成獨特的 OG 圖片,請在 blog 資料夾內添加一個 opengraph-image.ts 檔案,並從 next/og 導入 ImageResponse 建構函式:

import { ImageResponse } from 'next/og'
import { getPost } from '@/app/lib/data'

// 圖片元數據
export const size = {
  width: 1200,
  height: 630,
}

export const contentType = 'image/png'

// 圖片生成
export default async function Image({ params }: { params: { slug: string } }) {
  const post = await getPost(params.slug)

  return new ImageResponse(
    (
      // ImageResponse JSX 元素
      <div
        style={{
          fontSize: 128,
          background: 'white',
          width: '100%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        {post.title}
      </div>
    )
  )
}

ImageResponse 支援常見的 CSS 屬性,包括 flexbox 和絕對定位、自訂字體、文字換行、置中和嵌套圖片。查看支援的 CSS 屬性完整列表

須知事項

  • 範例可在 Vercel OG Playground 查看。
  • ImageResponse 使用 @vercel/ogsatoriresvg 將 HTML 和 CSS 轉換為 PNG。
  • 僅支援 flexbox 和部分 CSS 屬性。進階佈局(如 display: grid)無法使用。

On this page