Content Authoring Guidelines
This document provides guidelines for creating and managing content within projects built with this Astro Performance Starter template.
Getting Started
Section titled “Getting Started”- Content Location: All structured content uses Astro’s Content Collections API in
src/content/ - Validation: Run
pnpm run checkto validate TypeScript and content schemas - Configuration: Content collection schemas are defined in
src/content.config.ts
Content Collections Setup
Section titled “Content Collections Setup”The template ships six content collections — projects, blog, navigation, bio, experience, and adr — that you can extend. The adr collection is unusual: it loads docs/adr/NNN-*.md so decision records publish as web routes (ADR-062).
Blog Collection Example
Section titled “Blog Collection Example”The full blog schema, as defined in src/content.config.ts:
// src/content.config.ts (excerpt — see the file for all six collections)import { defineCollection } from "astro:content";import { glob } from "astro/loaders";import { z } from "astro/zod";
const blogCollection = defineCollection({ loader: glob({ pattern: "**/[^_]*.{md,mdx}", base: "./src/content/blog" }), schema: ({ image }) => z.object({ title: z.string(), description: z.string().max(160), date: z.date(), updated: z.date().optional(), draft: z.boolean().default(false), featured: z.boolean().default(false), cover: image().optional(), coverAlt: z.string(), // Required for accessibility when cover image is used cardImage: image().optional(), tags: z.array(z.string()).default([]), technologies: z.array(z.string()).default([]), author: z.string().default("Your Name"), // Default author readingTime: z.number().optional(), // Optional: can be calculated canonicalUrl: z.url().optional(), relatedPosts: z.array(z.string()).optional(), // ids of related posts }),});
export const collections = { projects: projectsCollection, blog: blogCollection, navigation: navigationCollection, bio: bioCollection, experience: experienceCollection, adr: adrCollection,};Note that coverAlt is required even when cover is omitted — every post frontmatter needs it.
Creating Content
Section titled “Creating Content”- Create collection directory:
src/content/[collection-name]/ - Add content files: Use
.mdor.mdxformat - Include frontmatter: Match your schema requirements
- Validate: Run
pnpm run checkto ensure type safety
Using MDX Components
Section titled “Using MDX Components”The template supports MDX for rich content with components:
---title: "Example Post"description: "Demonstrating MDX components"date: 2026-01-01coverAlt: ""---
import Image from '@/components/atoms/Image.astro';import exampleImage from './example.jpg';
# My Post
Regular markdown content works as expected.
<Image src={exampleImage} alt="Example image" />
You can also use any Astro components in your MDX files.Figure, Grid, and Callout (from src/components/mdx/) are pre-registered via astro.config.mjs and need no import; links and blockquotes are also rendered by the Link and Blockquote components there. Anything else — including Image — must be imported inside the MDX file.
Image Guidelines
Section titled “Image Guidelines”- Location: Store images next to content files or in
src/assets/ - Optimization: Use the template’s
Imageatom (src/components/atoms/Image.astro), which wrapsastro:assetswith responsivewidths/densitiesdefaults, lazy loading, and async decoding - Formats: the atom outputs a single format per image — AVIF by default, overridable with the
formatprop; SVG sources pass through unchanged. Astro’s raw<Image />fromastro:assetsdoes not apply this default. - Alt text: Always include descriptive alt text for accessibility
---import Image from '@/components/atoms/Image.astro';import myImage from '../assets/example.jpg';---
<Image src={myImage} alt="Descriptive alt text" />Content Workflow
Section titled “Content Workflow”- Plan content structure using Content Collections
- Create schema in
src/content.config.ts - Write content in MDX format with proper frontmatter
- Preview locally with
pnpm dev - Validate with
pnpm run check - Deploy using your preferred hosting platform