公開日・更新日メタデータの必要性と実装方法
なぜ公開日・更新日メタデータが必要なのか
1. コンテンツの鮮度を示す
検索エンジンとユーザーは、情報の新しさを重視します。特に:
- ニュース記事
- 技術記事(フレームワークのバージョン情報など)
- 市況分析(株式、経済データ)
- ハウツー記事(最新手法)
これらは、古い情報が無価値または有害になる可能性があります。
公開日・更新日を明示することで:
- ユーザーが情報の鮮度を判断できる
- 検索エンジンが最新コンテンツを優先的にランク付け
- AI検索が引用時に「この情報は2025年11月時点のもの」と注釈
2. Googleの「フレッシュネス」アルゴリズム
Googleは2011年から「Freshness Update」を導入しており、特定のクエリに対して新しいコンテンツを優先します。
フレッシュネスが重視されるクエリ:
- 時事ニュース(「○○社の最新決算」)
- 定期的に変わる情報(「2025年の確定申告方法」)
- 頻繁に更新される話題(「ChatGPT 使い方」)
公開日・更新日がないと、コンテンツの鮮度をGoogleは正確に判断できず、ランキングで不利になります。
3. AI検索エンジンでの引用精度
ChatGPT Search、Perplexity、Google SGEなどは、情報の信頼性を判断する際に公開日・更新日を重視します。
例:
ユーザー: 「NvidiaのH100の性能は?」
AI: 「2025年11月の情報によると、H100は... (出典: log.eurekapu.com, 2025年11月24日公開)」
日付がないと:
- 引用されにくい
- 古い情報と判断される
- 信頼性が低下
4. リッチスニペットに表示される
Googleの検索結果で、記事の公開日が表示される「リッチスニペット」を得られます:
Nvidiaの堀:競合他社が直面する「無理ゲー」な9つの壁
log.eurekapu.com › blog › nvidia-moat
2025年11月24日 — Nvidiaには何重もの「防御壁」があり、正面から戦って...
→ クリック率(CTR)が向上
5. ユーザー体験の向上
ユーザーは「この情報は今でも有効か?」を気にします。
公開日・更新日が明示されていると:
- 安心して情報を利用できる
- 古い情報を誤って使うリスクが減る
- サイトの信頼性が向上
どのように実装するか
必要なメタデータ
1. HTMLメタタグ(OGP)
<meta property="article:published_time" content="2025-11-27T00:00:00+09:00" />
<meta property="article:modified_time" content="2025-11-27T14:30:00+09:00" />
2. JSON-LD構造化データ
{
"@context": "https://schema.org",
"@type": "Article",
"datePublished": "2025-11-27",
"dateModified": "2025-11-27"
}
3. HTMLタグ(セマンティック)
<time datetime="2025-11-27" itemprop="datePublished">2025年11月27日</time>
ISO 8601形式の日時
公開日・更新日はISO 8601形式で指定します:
日付のみ:
2025-11-27
日時(タイムゾーン付き):
2025-11-27T14:30:00+09:00
T:日付と時刻の区切り+09:00:日本標準時(JST)のオフセット
今回のプロジェクトにおける実装
パターン1:Markdown記事のフロントマター
content/2025-11-27/article.mdの例:
---
title: 記事タイトル
description: 記事の説明
publishedAt: 2025-11-27
tags: [SEO, Nuxt]
---
# 記事本文
...
パターン2:動的記事ページ(...slug.vue)
実装状況: ✅ 実装済み(2025-11-28)
ファイル: apps/web/app/pages/[...slug].vue
Markdownコンテンツを動的に表示するページで、OGPメタデータとJSON-LD構造化データを自動生成します。
実装内容
基本的なOGP・JSON-LD構造化データは既に実装済みでしたが、更新日(updatedAt)のサポートを追加しました。
更新日対応を追加した理由:
- 記事を更新した際に、更新日を明示することでSEO評価が向上
- AI検索エンジンが「最新の更新は○○日」と認識できる
- ユーザーが「この情報は最近更新されている」と判断可能
コード例
<script setup lang="ts">
import { computed } from "vue"
import { queryCollection } from "#imports"
const route = useRoute()
const docPath = computed(() => {
const normalized = route.path.replace(/\/$/, "")
return normalized === "" ? "/" : normalized
})
const { data: doc } = await useAsyncData(
`content-${docPath.value}`,
() => queryCollection("pages").path(docPath.value).first(),
{ watch: [docPath] }
)
// OGPメタデータ
useSeoMeta({
title: () => doc.value?.title || 'ページが見つかりません',
description: () => doc.value?.description || '',
// 公開日・更新日
articlePublishedTime: () => doc.value?.publishedAt || '',
// ✅ updatedAtがあればそれを使用、なければpublishedAtを使用
articleModifiedTime: () => doc.value?.updatedAt || doc.value?.publishedAt || '',
articleAuthor: 'log.eurekapu.com',
// OGP
ogType: 'article',
ogUrl: () => `https://log.eurekapu.com${docPath.value}`,
ogImage: 'https://log.eurekapu.com/favicon.svg',
})
// JSON-LD構造化データ
useHead({
script: computed(() => {
if (!doc.value) return []
return [
{
type: 'application/ld+json',
children: JSON.stringify({
'@context': 'https://schema.org',
'@type': 'Article',
headline: doc.value.title || 'Untitled',
description: doc.value.description || '',
datePublished: doc.value.publishedAt || '',
// ✅ updatedAtがあればそれを使用、なければpublishedAtを使用
dateModified: doc.value.updatedAt || doc.value.publishedAt || '',
author: {
'@type': 'Person',
name: 'log.eurekapu.com'
},
publisher: {
'@type': 'Organization',
name: 'log.eurekapu.com',
logo: {
'@type': 'ImageObject',
url: 'https://log.eurekapu.com/favicon.svg'
}
},
image: 'https://log.eurekapu.com/favicon.svg',
url: `https://log.eurekapu.com${docPath.value}`,
})
}
]
})
})
</script>
<template>
<main>
<template v-if="doc">
<DocPage :doc="doc" />
</template>
</main>
</template>
スキーマ定義の追加
content.config.tsにupdatedAtフィールドを追加:
// apps/web/content.config.ts
schema: z.object({
title: z.string().optional(),
description: z.string().optional(),
path: z.string().optional(),
tags: z.array(z.string()).optional(),
publishedAt: z.coerce.date().optional(),
updatedAt: z.coerce.date().optional() // ✅ 追加
})
パターン3:個別ブログページ(Vue)
実装状況: ⚠️ 今回は対象外(手動実装を推奨)
対象: pages/blog/*.vue
個別のVueコンポーネントで作成されたブログページ(Markdownではなく、直接Vueで記述)です。
今回実装しなかった理由
- 既存実装との整合性
- 既存の個別Vueページには独自のメタデータ実装がある可能性
- 一律で自動化すると既存の設定を上書きするリスク
- 実装範囲の明確化
- 今回の実装はMarkdownコンテンツページの自動化がメイン
- Vueページは手動で必要に応じて実装する方が柔軟
- ページごとのカスタマイズ性
- Vueページは独自のOGP画像やメタデータを持つことが多い
- 自動化より手動実装の方が適切
実装する場合のコード例
必要に応じて、以下のパターンで手動実装してください:
<script setup lang="ts">
const publishedDate = '2025-11-24'
const updatedDate = '2025-11-25' // オプション:更新した場合のみ
useSeoMeta({
title: 'Nvidiaの堀:競合他社が直面する「無理ゲー」な9つの壁',
description: 'Nvidiaには何重もの「防御壁」があり、正面から戦って勝つのは実質不可能である理由。',
// 公開日・更新日
articlePublishedTime: publishedDate,
articleModifiedTime: updatedDate || publishedDate, // 更新日があればそれを使用
articleAuthor: 'log.eurekapu.com',
// OGP
ogType: 'article',
ogUrl: 'https://log.eurekapu.com/blog/nvidia-moat',
ogImage: 'https://log.eurekapu.com/images/nvidia-moat-perspective.svg',
})
useHead({
script: [
{
type: 'application/ld+json',
children: JSON.stringify({
'@context': 'https://schema.org',
'@type': 'Article',
headline: 'Nvidiaの堀:競合他社が直面する「無理ゲー」な9つの壁',
description: 'Nvidiaには何重もの「防御壁」があり、正面から戦って勝つのは実質不可能である理由。',
datePublished: publishedDate,
dateModified: updatedDate || publishedDate, // 更新日があればそれを使用
author: {
'@type': 'Person',
name: 'log.eurekapu.com'
},
publisher: {
'@type': 'Organization',
name: 'log.eurekapu.com',
logo: {
'@type': 'ImageObject',
url: 'https://log.eurekapu.com/favicon.svg'
}
},
image: 'https://log.eurekapu.com/images/nvidia-moat-perspective.svg',
url: 'https://log.eurekapu.com/blog/nvidia-moat',
})
}
]
})
</script>
<template>
<div class="page-container">
<main>
<article class="content-wrapper">
<header class="article-header">
<h1>Nvidiaの堀:競合他社が直面する「無理ゲー」な9つの壁</h1>
<p class="published-date">
<time :datetime="publishedDate">2025.11.24</time>
<time v-if="updatedDate" :datetime="updatedDate">(更新: 2025.11.25)</time>
</p>
</header>
<!-- 記事本文 -->
</article>
</main>
</div>
</template>
パターン4:DocPageコンポーネントで公開日を表示
実装状況: ✅ 実装済み(2025-11-28)
ファイル: apps/web/app/components/DocPage.vue
Markdownコンテンツを表示するコンポーネントで、記事の公開日・更新日をユーザーに視覚的に表示します。
実装した理由
- ユーザー体験の向上
- メタデータだけでなく、記事内に日付を表示することで、ユーザーが情報の鮮度を即座に判断可能
- 「この情報は最近のものか?」をページを開いた瞬間に確認できる
- SEOの観点
<time itemprop="datePublished">タグは検索エンジンが記事本体内で日付を認識- OGPやJSON-LDだけでなく、HTMLセマンティクスとしても重要
- パンくずリストとの役割分担
- パンくずリスト: ディレクトリ構造のナビゲーション(例:
2025-11-27) - DocPage内の日付: 記事メタデータとして、より明確に表示(例: "公開: 2025年11月27日")
- 重複を許容することで、両方の役割を果たす
- パンくずリスト: ディレクトリ構造のナビゲーション(例:
実装内容
追加した機能:
- 公開日の表示(日本語フォーマット: "2025年11月27日")
- 更新日の条件付き表示(公開日と異なる場合のみ)
- セマンティックHTML(
<time>タグ、itemprop属性)
コード例:
<script setup lang="ts">
import { computed } from "vue"
const props = defineProps<{ doc: ParsedContent }>()
// 公開日のフォーマット
const formattedDate = computed(() => {
const value = props.doc.publishedAt
if (!value) return ""
const date = typeof value === "string" ? new Date(value) : value
if (Number.isNaN(date.getTime())) return ""
return new Intl.DateTimeFormat("ja-JP", { dateStyle: "medium" }).format(date)
})
const isoDate = computed(() => {
const value = props.doc.publishedAt
if (!value) return ""
const date = typeof value === "string" ? new Date(value) : value
if (Number.isNaN(date.getTime())) return ""
return date.toISOString()
})
// 更新日のフォーマット
const formattedUpdatedDate = computed(() => {
const value = props.doc.updatedAt
if (!value) return ""
const date = typeof value === "string" ? new Date(value) : value
if (Number.isNaN(date.getTime())) return ""
return new Intl.DateTimeFormat("ja-JP", { dateStyle: "medium" }).format(date)
})
const isoUpdatedDate = computed(() => {
const value = props.doc.updatedAt
if (!value) return ""
const date = typeof value === "string" ? new Date(value) : value
if (Number.isNaN(date.getTime())) return ""
return date.toISOString()
})
// 更新日を表示するかどうか(公開日と異なる場合のみ)
const showUpdatedDate = computed(() => {
if (!props.doc.updatedAt || !props.doc.publishedAt) return false
const published = new Date(props.doc.publishedAt)
const updated = new Date(props.doc.updatedAt)
return updated.getTime() !== published.getTime()
})
</script>
<template>
<div class="doc-container">
<article class="doc">
<header v-if="doc.tags?.length || doc.publishedAt" class="doc__header">
<ul v-if="doc.tags?.length" class="doc__tags">
<li v-for="tag in doc.tags" :key="tag">#{{ tag }}</li>
</ul>
<!-- ✅ 公開日・更新日の表示 -->
<div v-if="doc.publishedAt" class="doc__meta">
<time :datetime="isoDate" itemprop="datePublished">
公開: {{ formattedDate }}
</time>
<time v-if="showUpdatedDate" :datetime="isoUpdatedDate" itemprop="dateModified">
更新: {{ formattedUpdatedDate }}
</time>
</div>
</header>
<div ref="bodyEl" class="doc__body">
<ContentRenderer :value="doc" />
</div>
</article>
<div class="doc-toc">
<TableOfContents :links="doc.body?.toc?.links" class="toc-wrapper" />
</div>
</div>
</template>
<style scoped>
.doc__meta {
display: flex;
flex-wrap: wrap;
gap: 1rem;
color: #6b7280;
font-size: 0.875rem;
margin-top: 0.5rem;
}
.doc__meta time {
font-weight: 500;
}
</style>
フロントマターの書き方
---
title: 記事タイトル
description: 記事の説明
publishedAt: 2025-11-27
updatedAt: 2025-11-28 # オプション:更新した場合のみ指定
tags: [SEO, Nuxt]
---
表示結果:
publishedAtのみ指定: 「公開: 2025年11月27日」updatedAtも指定(かつ異なる日付): 「公開: 2025年11月27日 更新: 2025年11月28日」
検証方法
1. Google Rich Results Test
- https://search.google.com/test/rich-results
- URLを入力して「公開日」が認識されているか確認
2. Schema Markup Validator
- https://validator.schema.org/
- JSON-LDの
datePublishedとdateModifiedを確認
3. Google Search Console
- 「拡張機能」→「リッチリザルト」
- エラーと警告を確認
4. ブラウザDevTools
// OGPメタタグを確認
document.querySelector('meta[property="article:published_time"]')?.content
// JSON-LDを確認
JSON.parse(document.querySelector('script[type="application/ld+json"]')?.textContent)
よくある間違い
❌ 日付形式が不正
<meta property="article:published_time" content="2025/11/27" />
✅ ISO 8601形式を使用
<meta property="article:published_time" content="2025-11-27" />
❌ 公開日が欠落
useSeoMeta({
title: '記事タイトル',
description: '説明',
// articlePublishedTime がない
})
✅ 公開日を必ず設定
useSeoMeta({
title: '記事タイトル',
description: '説明',
articlePublishedTime: '2025-11-27',
})
❌ HTMLに日付が表示されていない
<article>
<h1>記事タイトル</h1>
<p>本文...</p>
<!-- ユーザーが公開日を見られない -->
</article>
✅ HTMLに日付を表示
<article>
<h1>記事タイトル</h1>
<time datetime="2025-11-27">2025年11月27日</time>
<p>本文...</p>
</article>
まとめ
公開日・更新日メタデータは:
- コンテンツの鮮度を検索エンジンとユーザーに伝える
- Googleのフレッシュネスアルゴリズムで有利
- AI検索での引用精度を向上
- リッチスニペットでCTRを向上
MarkdownのフロントマターpublishedAtを設定し、OGP・JSON-LD・HTMLの3箇所に反映することが重要です。