[Astro] 記事ページに JSON-LD 構造化データ(BlogPosting)とOGPを入れる
Tech検索結果やSNSでの見え方のために、記事ページに JSON-LD 構造化データと OGP メタタグを入れました。Astro なら frontmatter の値を流し込むだけなので簡単です。
JSON-LD(BlogPosting)
記事レイアウトで、frontmatter の値から BlogPosting を組み立てて <script type="application/ld+json"> に流し込みます。set:html={JSON.stringify(...)} を使うのがポイント。
---
// src/layouts/BlogPostLayout.astro
import { SITE } from '@/data/site';
const { post } = Astro.props;
const { title, description, pubDate, updatedDate, thumbnail } = post.data;
const pageUrl = `${SITE.url}/blog/${post.id}/`;
---
<script is:inline type="application/ld+json" set:html={JSON.stringify({
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: title,
description: description,
datePublished: pubDate.toISOString(),
dateModified: (updatedDate || pubDate).toISOString(),
author: { '@type': 'Person', name: SITE.author },
publisher: { '@type': 'Organization', name: SITE.title },
mainEntityOfPage: { '@type': 'WebPage', '@id': pageUrl },
...(thumbnail ? { image: thumbnail } : {}),
})} />
ポイント。
- 日付は
toISOString()で ISO 8601 にする(pubDateはz.coerce.date()で Date 型なのでそのまま変換できる)。 dateModifiedはupdatedDateがあればそれを、無ければpubDateを使う。imageは thumbnail があるときだけ入れる(スプレッド構文で条件付き追加)。
公開後は Google のリッチリザルトテストで検証できます。
OGP メタタグ
OGP は <head> にメタタグを並べるだけ。共通レイアウトで Props から流し込みます。
---
// src/layouts/BaseLayout.astro
const { title, description, ogImage } = Astro.props;
const canonicalUrl = new URL(Astro.url.pathname, SITE.url);
---
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:type" content="website" />
<meta property="og:url" content={canonicalUrl} />
{ogImage && <meta property="og:image" content={ogImage} />}
<meta name="twitter:card" content="summary" />
ハマりどころ:og:image とサムネイルは別物
注意点として、記事一覧のサムネイル画像と OGP 画像(og:image)は分けて考える必要があります。
このブログのサムネイルは SVG ですが、og:image に SVG を指定しても 多くの SNS はレンダリングしません。そのため、
- サイト内のカード/ヘッダー画像 → SVG でOK
- SNS シェア用の
og:image→ PNG/JPG を別途用意
という整理にしています(JSON-LD の image には SVG パスでも入れていますが、SNS のカード表示用には別途ラスタ画像が必要)。サムネを SVG で量産する話はこちら。
メモ
- JSON-LD は
set:html={JSON.stringify(obj)}でオブジェクトから安全に出力できる。 - 構造化データは Search Console の「拡張」やリッチリザルトテストで検証する。
- OGP 画像は SVG 不可。SNS 重視なら専用のラスタOGPを用意する。
Astro, SEO