Skip to content

docs(blog): add blog with halation/FFmpeg post#119

Merged
RichardBray merged 6 commits into
mainfrom
docs/blog-launch
Jun 21, 2026
Merged

docs(blog): add blog with halation/FFmpeg post#119
RichardBray merged 6 commits into
mainfrom
docs/blog-launch

Conversation

@RichardBray

Copy link
Copy Markdown
Member

What

Starlight site gets a /blog index and a per-post page driven by an Astro content collection (Markdown frontmatter, JSON-LD Article + optional FAQPage, per-post OG image via the Base layout).

First published post

Halation in FFmpeg vs one Hance flag. Real sunflower before/after images for both pipelines, the exact filter_complex, and the equivalent CLI flags.

Also includes

  • Dehancer/FilmConvert comparison post (flagged draft: true, stays unlisted until it ships)
  • Nav entry for /blog
  • Base.astro accepts a per-page OG image prop (falls back to /og-card.png)

Test

bun run build from packages/docs. The draft post is filtered from the index and from getStaticPaths, so it isn't routed or listed.

Split out of #118 so the dither fix and the blog can ship independently.

Starlight site gets a /blog index and a per-post page driven by an
Astro content collection (Markdown frontmatter, JSON-LD Article +
optional FAQPage, per-post OG image via the Base layout).

First published post: halation in FFmpeg vs one Hance flag. Real
sunflower before/after images for both pipelines, the exact
filter_complex, and the equivalent CLI flags. Dehancer/FilmConvert
comparison post is included but flagged draft:true so it stays
unlisted until it ships.

@RichardBray RichardBray left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blog infra is clean. Content collection + JSON-LD + per-post OG image is exactly the right shape. Posts are well-written and honest (the Dehancer post credits competitors on fidelity). One nit on heroImage validation below, otherwise good to merge.

The split from #118 was clean - no docs file references anything in the dither code, and the dither code doesn't touch anything in packages/docs/.

Comment thread packages/docs/src/content.config.ts Outdated
pubDate: z.coerce.date(),
author: z.string().default("Richard Oliver Bray"),
// Header image: public path (e.g. "/blog/foo.png"). Also used as the
// per-post OG/Twitter card. Kept a string (not an Astro asset) so a

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: the comment says heroImage is kept as a plain string so "a not-yet-created file doesn't fail the build." That's convenient for drafting, but it means a published post with a typo'd heroImage will silently render a broken <img> in production - both on the post page ([...slug].astro:43) and on the index (index.astro:46), plus a broken OG card.

Two options:

  1. Validate non-draft posts at build time. Add a ref-style check that fails the build when !data.draft && !existsSync('public/' + data.heroImage). Drafts stay loose, published posts are guaranteed to have the asset.

  2. Keep it loose but warn. Log a build-time warning when the file is missing. Less safe but zero friction.

Option 1 is more aligned with how the rest of the site handles slugs - astro.config.mjs already fails the build on a missing slug, so a missing hero image failing too is consistent.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch - went with option 1. Added a .refine on the blog schema in content.config.ts that fails the build when a non-draft post's heroImage is missing from public/. Drafts stay loose so they can point at a not-yet-created asset. Mirrors the slug-validation behaviour you mentioned. Fixed in f847dc7.

- Click in-article blog images to open fullscreen, click again to zoom
  2.5x with cursor-follow pan, X/Esc/backdrop to close (native <dialog>)
- Explain the magenta cast and reword the FFmpeg crudeness paragraphs
Mirrors how a bad slug already fails the build. Drafts stay loose so they
can reference a not-yet-created asset; non-draft posts must have the file
in public/ or the build errors instead of shipping a broken <img> and OG card.

Addresses PR #119 review feedback.
@RichardBray RichardBray merged commit d6f9d24 into main Jun 21, 2026
RichardBray added a commit that referenced this pull request Jun 21, 2026
Mirrors how a bad slug already fails the build. Drafts stay loose so they
can reference a not-yet-created asset; non-draft posts must have the file
in public/ or the build errors instead of shipping a broken <img> and OG card.

Addresses PR #119 review feedback.
@RichardBray RichardBray deleted the docs/blog-launch branch June 21, 2026 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant