Imported from flcdrg/astro-blog-engine (
AGENTS.md). Install upstream withnpx skills add flcdrg/astro-blog-engine. Copyright stays with the author.
Instructions
This file provides guidance to agents when working with code in this repository.
This is a static blog (Dave's Daydreams) built with Astro v7, deployed to Cloudflare Pages.
Tooling
- Node:
>=24 <25(seepackage.jsonengines). Usepackage.jsonas the node-version-file in CI. - Package manager: pnpm only. Do not suggest npm/yarn commands.
Commands
pnpm install
pnpm dev # local dev server (future-dated posts visible in dev, hidden in prod)
pnpm build # runs astro check then astro build; outputs to dist/
pnpm preview
pnpm run validate-frontmatter # checks posts don't have unfilled template placeholders
pnpm lint # markdownlint-cli2 on markdown files
pnpm lint:fix
pnpm verify # run all Verify.Cli snapshot checks (verify:dist, verify:post, verify:index)
The verify* scripts require dist/ to exist (run pnpm build first) and the verify (Verify.Cli) tool to be installed.
Agent workflow guardrails
- Quote any path containing square brackets when using shell commands (for example
src/pages/[...slug].astro,src/pages/[year]/index.astro, andsrc/pages/tags/[tag].astro), or temporarily disable globbing for that command. - For metadata requests that span multiple pages or posts, do one scan-first pass and return a consolidated patch rather than a sequence of small per-page edits.
- For JSON-LD and rich-results troubleshooting, validate in this order: generated
dist/*.html, live page HTML, then external validator output. Treat tool disagreement as non-blocking unless the generated markup differs. - Keep the single JSON-LD script per page pattern. Prefer page-specific JSON-LD data passed into the layout over emitting multiple unrelated script blocks per page.
- For content or instruction-only changes, avoid commands that can mutate dependency state (
pnpm install, upgrades, lockfile regeneration) unless explicitly requested. If unexpected dependency changes appear, stop immediately and ask how to proceed. - After edits, run the smallest relevant verification set and report results: metadata-only (
pnpm run validate-frontmatter), route/layout/head changes (pnpm build), snapshot-sensitive output (pnpm verifywhen requested).
Architecture
Content collection
- Blog posts live in
src/posts/<year>/YYYY-MM-DD-slug.md(or.mdx). - The collection loader (
src/content.config.ts) strips theYYYY-MM-DD-date prefix (first 16 chars) from the filename and builds the post ID asyyyy/MM/slugusing thedatefront matter field parsed with Luxon. src/scripts/filters.tsexportsonlyCurrent— future-dated posts are excluded in production builds but shown in dev mode.- Collection schema is in
src/content.config.ts; importzfromastro/zod, notastro:content.
Build format and URLs
build.formatis set to'file'— pages render aspage.html, notpage/index.html. This must not be changed.- Because of
build.format: 'file',@astrojs/sitemaphard-codes a stream-level replacement that strips trailing slashes from all<loc>values. A custom inline integration (blog-post-processinginastro.config.ts) post-processesdist/sitemap-0.xmlafter the build to restore the trailing slash on the root URL only. - Canonical URLs are computed in
src/scripts/canonical.ts: strips.htmlextension, maps/index→/. - The
astroCanonicalintegration (scripts/astroCanonical.ts) validates every HTML page has a correct canonical tag at build time; the build fails if any are missing or wrong.
Layouts and slots
src/layouts/BaseLayout.astro— root layout; handles<head>, nav, footer, canonical link, and site-wide JSON-LD. The JSON-LD is an@graphcontaining anOrganization(withsameAssocial links) and aWebSite(with aSearchActionpointing at/tags/{search_term_string}).src/layouts/MarkdownPostLayout.astro— wraps blog post content; adds Disqus comments and post-specific JSON-LD: aBlogPostingplus one or moreBreadcrumbListtrails — a primary archive trail (Archive → Year → Post) and a secondary trail per tag (Tags → Tag → Post). Breadcrumb trails deliberately omit the site root.- Posts render up to three related posts (by shared tags) and previous/next links. Both are computed in
src/pages/[...slug].astroand only link to indexable posts (seesrc/scripts/indexing.ts). BaseLayoutexposes asite-titleslot (default:<SiteTitle />). Onlyindex.astrooverrides it.BaseLayoutalso exposes aheadslot for extra<head>content.- Google Analytics (gtag) is only injected when the resolved
Astro.sitehost isdavid.gardiner.net.au, so preview deploys don't emit analytics. public/_headerssendsX-Robots-Tag: noindexfor*.workers.devhosts (production and preview URLs).
Sitemap (astro.config.ts)
- The
serializecallback strips trailing slashes from all URLs and injectslastmod. For blog posts it is the later of the front matterdateandmodified_time(not git history, which bulk edits make inaccurate);/aboutand/speakingusegit log. - Post files are resolved by reconstructing the file path from the URL pattern
/YYYY/MM/slug. - Site URL defaults to
https://david.gardiner.net.au; overridden byDEPLOY_PRIME_URLenv var.
Dates
- Use Luxon for all date handling. Display relative to
Australia/Adelaidetimezone. DateTime.fromISO(iso, { zone: "Australia/Adelaide" }), format viatoLocaleString.
Diagrams
- Mermaid diagrams are supported via the
astro-mermaidintegration (astro.config.ts), configured with theforesttheme,autoTheme, and thelogos/iconoiricon packs (fetched from unpkg at build time).
Verification / snapshot testing
verified/holds.verified.*snapshot files used by Verify.Cli for regression testing in CI.- Run locally with
pnpm verify(afterpnpm build). The scripts verifydist/feed.xml,dist/index.html, and a specific post HTML file (dist/2025/07/azure-pipeline-template-expression.html); CI also verifies HTTP redirect traces. - Scrubbers in the
verify:*scripts normalize hashed/_astro/asset names,title="..."attributes, the Astro generator version, and thedata-image-componentmarker so snapshots stay stable across builds. - To update a snapshot, copy the
.received.*file over the corresponding.verified.*file.
CI/CD
- PR builds:
pnpm build --devOutput(includes future-dated posts). - Production builds:
pnpm buildon push tomain. - Deployed to Cloudflare Pages via Wrangler (
wrangler deployfor production,wrangler versions uploadfor PR previews). - PR preview jobs also run
Test-HttpRedirects.ps1and verify HTTP trace snapshots. - Link checking uses lychee; Lighthouse CI runs on every build.
- The
.astro/directory anddist/are cached in CI keyed onpnpm-lock.yaml.
Environment variables
DEPLOY_PRIME_URL— overrides the site URL (used in Cloudflare preview deploys).- Use
import.meta.envin Astro components/pages. Do not use hyphens in shell variable names.
Content schemas (Astro v7)
- Import
zfromastro/zod(not fromastro:contentorastro:schema). - Post front matter fields:
date(ISO datetime with offset, required),title(required),draft(optional bool, defaultsfalse),tags(string array, defaults["others"]),image(optional, resolved via Astro'simage()helper),imageAlt,description.
