Blog Post Authoring Conventions
Campaign Slug Prefix
Blog posts that belong to a marketing campaign use a campaign-prefixed slug: the folder under content/blog/ (and the published URL) starts with the campaign identifier.
Current campaigns and their prefixes:
| Campaign | Prefix | Example |
|---|---|---|
@atomic-ehr/codegen | atomic-ehr-codegen- | content/blog/atomic-ehr-codegen-python-fhir-types/ → /articles/atomic-ehr-codegen-python-fhir-types |
Why the prefix is mandatory for campaign posts:
- Keeps campaign posts grouped in the blog directory listing.
- Makes the published URL self-identifying — a reader seeing
/articles/atomic-ehr-codegen-*knows it's part of the same series without having to read the page. - Lets analytics filter campaign traffic by URL prefix without needing per-post UTM content fields.
Folder Structure
Each post is its own folder containing index.md and any co-located assets (images, diagrams):
content/blog/{slug}/
├── index.md
├── hero.png # optional post hero / social image
└── diagram.svg # optional inline images
Reference images from index.md with relative paths: .
Frontmatter
The frontmatter is a YAML-style object between --- markers at the top of index.md:
---
{
"title": "...",
"description": "One-line summary shown in listings and social cards.",
"date": "YYYY-MM-DD",
"author": "Full Name",
"reading-time": "N minutes",
"tags": ["Tag A", "Tag B"]
}
---
Tags are shared across the blog — reuse existing tags where possible (check other posts) rather than inventing new ones.
Updating an Older Post
When a post supersedes an older one, add an update notice at the top of the old post pointing to the new URL, and link back from the new post in the intro. See the pattern used in type-schema-python-sdk-for-fhir/index.md (superseded by atomic-ehr-codegen-python-fhir-types).




