[ TRANSMISSION_RECEIVED ] // February 22, 2026 // 8 min READ

_

Introducing the new blog system with content collections, co-located assets, and optimized images. Here's why it matters and how to use it.

[ SYSTEM_UPGRADE // NEW_FEATURES_DEPLOYED ]

Welcome to the first technical transmission from Anjung Sepi. Today, we’re diving into the infrastructure upgrades that power this blog. If you’re curious about how content collections work or why co-locating assets is a game-changer, this signal is for you.


The Problem: Old School Blogging

Before the upgrade, this blog used a simple file structure:

src/pages/blog/
├── index.astro           # Blog listing
└── my-first-post.astro   # Individual post

Images lived separately in /public/image/, scattered and disconnected from their posts. This worked for small blogs, but as content grows, it becomes a mess:

  • Orphaned images — Deleted posts leave behind unused images
  • No optimization — Images served as-is, no WebP/AVIF conversion
  • Hard to track — Which images belong to which post?
  • No type safety — Frontmatter was just vibes and prayers

The Solution: Content Collections

Astro’s Content Collections organize blog posts with type-safe frontmatter and co-located assets. Here’s the new structure:

src/content/blog/
└── post-slug/
    ├── index.mdx         # Post content
    ├── hero.png          # Post-specific images
    └── screenshots/
        └── step-1.png

Key Features

1. Type-Safe Frontmatter

Every blog post now has validated frontmatter defined in src/content/config.ts:

const blog = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    pubDate: z.string(),
    description: z.string(),
    tags: z.array(z.string()).optional(),
    author: z.string().optional(),
    readingTime: z.string().optional(),
    draft: z.boolean().optional().default(false),
  }),
});

Benefits:

  • ✅ TypeScript autocomplete for frontmatter fields
  • ✅ Build-time validation (catches typos early)
  • ✅ Draft support (draft: true hides from production)

2. Co-located Assets

Images live alongside their blog post:

src/content/blog/my-post/
├── index.mdx
├── featured-image.png
└── diagrams/
    └── architecture.webp

Why this matters:

Old WayNew Way
Images in /public/image/Images with post
Manual cleanup neededDeleted with post
Hard to track usageClear ownership
No optimizationAutomatic optimization

3. Optimized Images with BlogImage Component

The BlogImage component (src/components/BlogImage.astro) handles image optimization automatically:

---
import BlogImage from '../../../components/BlogImage.astro';
import screenshot from './screenshot.png';
---

<BlogImage 
  src={screenshot} 
  alt="A description for accessibility" 
  caption="Optional caption text" 
/>

What happens behind the scenes:

  1. Format conversion — Generates WebP and AVIF versions
  2. Responsive srcset — Multiple sizes for different screens
  3. Lazy loading — Images load only when visible
  4. Built-in styling — Terminal-themed borders and shadows

How to Create a New Blog Post

Step 1: Create the Folder

src/content/blog/my-awesome-post/

Step 2: Add Content File

src/content/blog/my-awesome-post/index.mdx

Step 3: Write Frontmatter

---
title: "My Awesome Post"
pubDate: "2026-02-22"
description: "A brief description for SEO and social sharing"
tags: ["tutorial", "astro"]
author: "your-name"
readingTime: "5 min"
draft: false
---

Your content starts here...

Step 4: Add Images (Optional)

Place images in the same folder:

src/content/blog/my-awesome-post/
├── index.mdx
└── hero.png

Step 5: Use Images in Content

---
import BlogImage from '../../../components/BlogImage.astro';
import hero from './hero.png';
---

<BlogImage 
  src={hero} 
  alt="Hero image for my post" 
  caption="This is an optional caption" 
/>

Real Example: This Blog Post

This very post uses the new system. Here’s how the file structure looks:

src/content/blog/content-collections-guide/
├── index.mdx              # This file
└── (future images here)

And in the content, I can import and use images like:

---
import BlogImage from '../../../components/BlogImage.astro';
import diagram from './architecture-diagram.png';
---

<BlogImage 
  src={diagram} 
  alt="System architecture diagram" 
  caption="How content collections work" 
/>

Migration Notes

If you’re migrating from the old system:

  1. Move posts from src/pages/blog/ to src/content/blog/
  2. Convert to MDX — Change .astro to .mdx
  3. Add frontmatter — Use the schema above
  4. Move images — Place in post folder
  5. Update imports — Use BlogImage component

For Shared Images

Some images are used across multiple posts (logos, icons, etc.). For these, use /public/image/:

<img src="/image/logo.png" alt="Logo" class="my-4" />

This bypasses optimization but works for shared assets.


Technical Deep Dive

How Dynamic Routes Work

The file src/pages/blog/[slug].astro creates dynamic routes:

---
import { getCollection } from 'astro:content';

export async function getStaticPaths() {
  const blogPosts = await getCollection('blog');
  
  return blogPosts.map((post) => ({
    params: { slug: post.slug },
    props: { post },
  }));
}
---

This generates:

  • /blog/first-transmission/
  • /blog/content-collections-guide/
  • /blog/your-future-post/

Build Process

During build:

  1. Content sync — Astro reads all index.mdx files
  2. Frontmatter validation — Checks against schema
  3. Image optimization — Generates WebP/AVIF variants
  4. Route generation — Creates HTML for each post
  5. Static output — Ready for deployment

Why This Matters

For Readers

  • ✅ Faster page loads (optimized images)
  • ✅ Better accessibility (alt text required)
  • ✅ Responsive design (works on all devices)

For Writers

  • ✅ Type-safe frontmatter (fewer errors)
  • ✅ Organized structure (easy to manage)
  • ✅ Draft support (work in progress hidden)
  • ✅ Automatic image optimization (no manual work)

For Developers

  • ✅ Build-time validation (catch issues early)
  • ✅ TypeScript integration (autocomplete!)
  • ✅ Clean architecture (scalable)
  • ✅ Easy maintenance (co-located assets)

What’s Next?

This system sets the foundation for:

  • Table of Contents — Auto-generated from headings
  • Related Posts — Based on tags/categories
  • Search — Full-text search across posts
  • RSS Feed — For RSS readers
  • Sitemap — Better SEO

Closing Thoughts

Content collections aren’t just a technical upgrade—they’re a workflow improvement. Writing blog posts is now cleaner, safer, and more maintainable.

The initial setup takes a bit of work, but the long-term benefits are worth it. Future-you will thank present-you for making this change.


[ END_OF_TRANSMISSION // QUESTIONS_WELCOME ]


Got questions about the new system? Want to suggest improvements? The signal is open.

AUTH: CACING [ END_OF_TRANSMISSION ]

> SHOW_RELATED_TRANSMISSIONS

Recommended Transmissions

Based on your current signal, these transmissions may interest you.