Skip to content

結構化資料 JSON-LD|Nuxt SEO

JSON-LD 結構化資料讓 Google 理解頁面類型,有機會在搜尋結果中顯示 rich results(如文章日期、搜尋框、FAQ 等)。所有 URL 必須使用 canonical domain,不可混用 www / non-www。

WebSite / Organization

全站首頁放一次,讓 Google 認識網站身份與站內搜尋:

useHead({
script: [{
type: 'application/ld+json',
innerHTML: JSON.stringify({
'@context': 'https://schema.org',
'@type': 'WebSite',
name: '網站名稱',
url: 'https://www.example.com/',
potentialAction: {
'@type': 'SearchAction',
target: 'https://www.example.com/search?q={search_term_string}',
'query-input': 'required name=search_term_string'
}
})
}]
})

Article / BlogPosting

每篇文章 / 知識庫頁面放一個,帶入 frontmatter 資料:

useHead({
script: [{
type: 'application/ld+json',
innerHTML: JSON.stringify({
'@context': 'https://schema.org',
'@type': 'Article',
headline: article.value.title,
description: article.value.description,
datePublished: article.value.publishedAt,
dateModified: article.value.updatedAt,
image: 'https://www.example.com/og/article.jpg',
url: `https://www.example.com/learn/${article.value.slug}/`
})
}]
})

必要欄位

  • headline:文章標題
  • description:文章摘要
  • datePublished:首次發布日期(ISO 8601)
  • dateModified:最後更新日期(ISO 8601)
  • image:文章代表圖,絕對 URL
  • url:文章 canonical URL

建議擴充欄位

{
author: {
'@type': 'Person',
name: '作者名稱'
},
publisher: {
'@type': 'Organization',
name: '品牌名稱',
logo: {
'@type': 'ImageObject',
url: 'https://www.example.com/logo.png'
}
},
mainEntityOfPage: {
'@type': 'WebPage',
'@id': 'https://www.example.com/learn/article-slug/'
}
}

Composable 封裝建議

將 JSON-LD 封裝成 composable,避免每頁重複寫:

composables/useArticleJsonLd.ts
export function useArticleJsonLd(article: {
title: string
description: string
publishedAt: string
updatedAt?: string
image?: string
url: string
}) {
const config = useRuntimeConfig()
const siteUrl = config.public.siteUrl
useHead({
script: [{
type: 'application/ld+json',
innerHTML: JSON.stringify({
'@context': 'https://schema.org',
'@type': 'Article',
headline: article.title,
description: article.description,
datePublished: article.publishedAt,
dateModified: article.updatedAt || article.publishedAt,
image: article.image
? `${siteUrl}${article.image}`
: `${siteUrl}/og-default.jpg`,
url: `${siteUrl}${article.url}`
})
}]
})
}

這樣頁面只需要:

useArticleJsonLd({
title: article.value.title,
description: article.value.description,
publishedAt: article.value.publishedAt,
updatedAt: article.value.updatedAt,
image: article.value.ogImage,
url: route.path
})

驗證方式

  1. Rich Results Test:貼上 production URL 檢查是否有錯誤。
  2. raw HTML grepcurl -L URL | grep "application/ld+json" 確認 SSR 有輸出。
  3. Chrome DevTools:在 Elements 搜尋 ld+json 確認內容。

完成標準

Checklist

JSON-LD 結構化資料檢查

P1

  • URL 全部使用 canonical domain
  • @id 不混 non-www
  • image 使用絕對 URL
  • 文章有 datePublished / dateModified
  • Rich Results Test 無重大錯誤
  • SSR raw HTML 已包含 JSON-LD(不只靠 client-side inject)