本文へ移動
aapp-hacks
← 記事一覧へ
著者
app-hacks
公開日
更新日
確認日

Astro / Content Collections / 公開管理

Astro Content Collectionsで下書きと公開日を安全に管理する

draftとpubDateを検証し、記事一覧・静的ルート・sitemapから未公開記事を安全に除外するAstroの設計を解説します。

Astro Content Collectionsで下書きと公開日を安全に管理する

下書きを記事一覧から隠すだけでは、未公開記事を安全に扱ったことになりません。静的ルートやSitemapに残っていれば、URLが生成されて検索や共有の対象になる可能性があります。公開状態は、Frontmatterの値、一覧、静的ルート、Sitemapを同じ条件でそろえて判断します。

この記事では、Astro Content CollectionsでdraftとpubDateを使い、公開記事だけを本番出力へ含める構成を説明します。

draftがfalseで公開日がある記事だけを一覧、詳細URL、Sitemapへ含める公開条件の図

公開条件をスキーマで定義する

まず、記事データが満たすべき条件をContent Collectionのスキーマに置きます。draftは明示的な公開状態、pubDateは公開済み記事に必要な日付として扱います。

const blogSchema = z
  .object({
    title: z.string().min(1),
    description: z.string().min(1),
    pubDate: z.coerce.date().nullable().default(null),
    draft: z.boolean().default(false),
    tags: z.array(z.string().min(1)).min(1),
  })
  .superRefine((post, context) => {
    if (!post.draft && !post.pubDate) {
      context.addIssue({
        code: z.ZodIssueCode.custom,
        message: '公開記事にはpubDateが必要です。',
        path: ['pubDate'],
      });
    }
  });

この条件により、公開扱いなのに日付がない記事をビルド時に止められます。逆に、下書きはdraft: trueとし、pubDateを設定しません。「将来公開する予定日」を下書きへ書くと、日付を公開日として扱う実装と衝突しやすくなるためです。

一覧と詳細ルートに同じ条件を使う

記事一覧で下書きを除外しても、getStaticPaths()が下書きを含めていれば詳細URLは生成されます。公開対象を絞る条件は、一覧と詳細ページで同じにします。

const isPublished = (post: CollectionEntry<'blog'>) =>
  !post.data.draft && Boolean(post.data.pubDate);

const publishedPosts = posts.filter(isPublished);

本番ではpublishedPostsから一覧と静的パスを作ります。開発中だけ下書きを確認したい場合は、開発環境かどうかを別の条件として加えます。開発用の表示条件をそのまま本番ルートの条件にしないことが重要です。

const includeDrafts = import.meta.env.DEV;
const routablePosts = posts.filter(
  (post) => includeDrafts || isPublished(post),
);

この例では、ローカル開発中は下書きのURLを確認でき、本番ビルドでは公開済み記事だけが生成されます。

Sitemapと内部リンクも公開状態に合わせる

Sitemap integrationは、実際に生成された公開ルートをもとにSitemapを作ります。そのため、下書きの詳細ルートを生成しないことがSitemap除外の前提です。記事一覧、前後の記事リンク、関連記事、RSSなどを実装している場合も、リンク元で公開条件をそろえます。

特に見落としやすいのは、下書きへの手書きリンクです。下書きが本番に存在しないなら、公開済み記事からそのURLへリンクしてはいけません。公開日より前に内部リンクを張る必要がある場合も、公開時にまとめて追加する方がリンク切れを防げます。

生成物で非掲載を確認する

公開条件の確認はソースだけで終えず、実際のビルド出力で行います。

npm run build
test ! -e dist/blog/draft-article/index.html
! rg -q 'draft-article' dist/sitemap-0.xml

一覧ページ、dist/blog/の詳細ルート、Sitemapを日英それぞれ確認します。下書きIDがどこにもないことと、公開対象の記事が意図したURLで生成されることを対で確認してください。

公開時の変更を小さくする

公開日に変更するのは、日英原稿のdraft、pubDate、必要ならupdatedDateとreviewedAtだけにします。その後にビルドと生成物確認を実行すれば、公開設定の変更と本文変更を混ぜずに履歴を追えます。

下書きの除外は、単一のフラグだけで解決する問題ではありません。スキーマ、一覧、静的パス、リンク、Sitemapを一つの公開条件で結ぶことで、意図しないURL生成を防げます。

関連記事