Open1

Astroのコンテンツコレクションの画像をPictureで表示する

mimimimi

https://docs.astro.build/ja/guides/images/
が公式だけどちょっと分かりにくい

src/content/config.tsでコレクションを設定するときに、image()スキーマヘルパーを使う

import { z, defineCollection } from "astro:content";

const interviewCollection = defineCollection({
  schema: ({ image }) =>
    z.object({
      date: z.date(),
      title: z.string(),
      description: z.string(),
      thumbnail: image().refine((img) => img.width >= 1080, {
        message: "カバー画像は幅1080ピクセル以上でなければなりません!",
      }),
      tags: z.array(z.string()),
    }),
});

export const collections = {
  interview: interviewCollection,
};

該当のastroファイルでPictureでそのまま受け取れる

---
import Layout from '../../layouts/Layout.astro';
import { getCollection } from 'astro:content';
import { Picture } from 'astro:assets';

const blogPosts = await getCollection('interview');

---
<Layout title='Interview'>
  <h1>Interview</h1>
  <ul>
    {blogPosts.map((post) => (
      <a href={`/interview/${post.slug}`}><li class="border border-gray-200 p-4">
        {post.data.thumbnail && (
          <Picture src={post.data.thumbnail} formats={['avif', 'webp']} alt={post.data.title} />
        )}
        <h2>{post.data.title}</h2>
        <p>{post.data.description}</p>
      </li></a>
    ))}
  </ul>
</Layout>

なんか原理が良く分からず暫くハマったけれど、分かってみるとなんでハマったのか分からないような。