Skip to content

Astro Setup

  • src/data/scribe.yaml committed to repo
  • framework: astro set in scribe.yaml
  • feature_image: z.string().optional() in content collection schema
  • draft: z.boolean().default(false) in schema
  • categories: z.array(z.string()).default([]) in schema
  • Post hero component reads feature_image
  • Post listing pages filter !p.data.draft
  • public/images/posts/ folder exists
  • Cloudflare Pages / GitHub Actions builds on push to main

Add scribe’s fields to src/content.config.ts:

const posts = defineCollection({
schema: z.object({
title: z.string(),
date: z.coerce.date(),
author: z.string().default(''),
categories: z.array(z.string()).default([]), // array, not string
tags: z.array(z.string()).default([]),
feature_image: z.string().optional(), // ← add this
draft: z.boolean().default(false), // ← add this
// ... your other fields
}),
});

Update your post hero component to read feature_image:

---
interface Props {
cover?: string;
feature_image?: string; // add this
title: string;
}
const { cover, feature_image, title } = Astro.props;
const heroImage = cover || feature_image;
---
<header class="post-hero">
{heroImage
? <img src={heroImage} alt={title} loading="eager" />
: <figure class="fallback"></figure>
}
</header>
const allPosts = await getCollection('posts');
const posts = allPosts.filter(p => !p.data.draft);

scribe uploads images to public/images/posts/. Astro serves public/ from the site root — URL becomes /images/posts/filename.webp.