0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Astro のコンテンツコレクションで、frontmatter に書いた項目が黙って消える

0
Posted at

個人開発のサービスのコラム(Astro 製)で、大きく書き直した記事に「更新日」を表示しようとしました。frontmatter に updatedDate を書いたのですが、エラーも警告も出ないのに、ページのどこにも反映されませんでした。

記事の frontmatter
---
title: "海外旅行の割り勘どうする?"
pubDate: 2026-03-26
updatedDate: 2026-10-01
---

原因:スキーマにない項目は取り除かれる

コンテンツコレクションのスキーマは、次のようになっていました。

src/content.config.ts(修正前)
const column = defineCollection({
  loader: glob({ pattern: '**/*.md', base: './src/content/column' }),
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.date(),
    tags: z.array(z.string()).optional(),
  }),
});

updatedDate がスキーマにありません。Astro のスキーマは zod で書きます。zod の z.object() は、スキーマにないキーをエラーにせず、取り除いて検証を通します。

zod だけで確かめると、次のようになります。

const { z } = require('zod');
const s = z.object({ title: z.string(), pubDate: z.date() });
const r = s.safeParse({ title: 't', pubDate: new Date(), updatedDate: new Date() });
console.log(r.success, Object.keys(r.data));
// true [ 'title', 'pubDate' ]

検証は成功します。しかし、結果から updatedDate が消えています。テンプレートで entry.data.updatedDate を読んでも、常に undefined です。

直し方:スキーマに足す

src/content.config.ts(修正後)
schema: z.object({
  title: z.string(),
  description: z.string(),
  pubDate: z.date(),
  // 記事を大きく書き直したときに設定する。ページの表示と構造化データ(dateModified)に使う
  updatedDate: z.date().optional(),
  tags: z.array(z.string()).optional(),
}),

あとはテンプレートで使うだけです。

記事ページ
{entry.data.updatedDate && (
  <time datetime={entry.data.updatedDate.toISOString()}>
    {entry.data.updatedDate.toLocaleDateString('ja-JP', { year: 'numeric', month: 'long', day: 'numeric' })}
  </time>
)}

SEO で困ること

今回は画面の表示だけでなく、構造化データの dateModified にも更新日を使っています。

レイアウト(抜粋)
dateModified: (updatedDate ?? pubDate).toISOString(),

updatedDate が消えていると、dateModified が黙って公開日のままになります。記事を書き直しても、検索エンジンに「更新された」と伝わりません。見た目では気づきにくく、エラーも出ないのが厄介なところです。

再発を防ぐ:未知のキーをエラーにする

書き間違い(updateDate など)も含めて気づきたい場合は、未知のキーをエラーにするスキーマにします。

// zod 4
schema: z.strictObject({ ... })

// zod 3 系
schema: z.object({ ... }).strict()

こうすると、スキーマにない項目が frontmatter にあったとき、ビルドがエラーで止まります。記事が多く、frontmatter を手で書くことが多いなら、こちらの方が安全です。

まとめ

  • Astro のコンテンツコレクションでは、スキーマにない frontmatter の項目は、エラーにならずに取り除かれる(zod の z.object() の動き)
  • 新しい項目を使うときは、まずスキーマに足す
  • 気づける仕組みにしたいなら、z.strictObject() で未知のキーをエラーにする

個人で開発している割り勘アプリ「WaliPro」のコラム(walipro.jp/column)で見つけた話でした。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?