Teardown: the Claude Code content workflow powering this site

A full teardown of the Claude Code content workflow behind aiagentstrategy.com. Astro for static HTML, Vercel for hosting, CLAUDE.md and brand docs for AI-controlled content operations.

· Page Sands

I’ve been writing about using Claude Code for GTM work. It’s only fair to show the content workflow behind the site itself.

This is a teardown of the three layers: the web framework, the hosting setup, and the Claude Code content workflow that runs the operation. The first two are straightforward. The third is where the interesting decisions live.

Web layer: Astro + Tailwind

The site runs on Astro. Seven dependencies in package.json. No client-side JavaScript framework.

Astro generates static HTML at build time. Every page ships as plain HTML and CSS. No React, no Vue, no hydration. That’s the main reason it scores 100 across all four Lighthouse categories without any optimization work.

The stack:

  • Astro 5.17 for static site generation
  • Tailwind CSS 4.2 via the Vite plugin for styling
  • MDX for posts that need HTML inside markdown (like the signal comparison table in the last post)
  • Sharp for image optimization at build time
  • @astrojs/sitemap and @astrojs/rss for SEO basics

The site has four page routes: homepage, about, blog archive, and individual blog posts. Five components: BaseHead (meta tags, Open Graph, PostHog), Header, Footer, HeaderLink, and FormattedDate. One global CSS file with custom theme variables on top of Tailwind.

Blog posts live in src/content/blog/ as markdown files. Astro’s content collections handle the schema validation (title, description, pubDate, optional heroImage). The filename becomes the URL slug. Writing a new post means creating a .md file with the right frontmatter and pushing to main.

There’s nothing unusual here. That’s the point. Astro is a good default for content sites because it stays out of the way.

Hosting layer: Vercel

The site deploys on Vercel. Push to main, Vercel builds, site is live. No CI config, no build scripts beyond astro build.

The one piece of config worth mentioning is vercel.json, which handles redirects from the old Webflow site. Ten permanent redirects covering every URL pattern that was indexed: /blogs to /blog, /about-page-sands to /about, /post/:slug to /blog, and several section pages that don’t exist anymore pointing back to the homepage.

This matters for SEO equity during a replatform. If someone bookmarked or linked to the old Webflow URL structure, they land on the right page instead of a 404. Claude Code generated these redirects by looking at the old sitemap.

Analytics runs through PostHog, loaded via a snippet in the BaseHead component. Async, no npm package, no impact on page load.

That’s the hosting layer. Vercel + a redirect file + an analytics snippet.

Claude Code content workflow

This is the layer that makes the site more than a static blog. It’s where the content operation lives.

How CLAUDE.md controls the content operation

Every Claude Code session starts by reading CLAUDE.md. This file is 80 lines of project instructions: what the site is, how posts are structured, where files go, what the writing rules are, and how the workflows run.

When I open Claude Code in this repo, it already knows the frontmatter schema for blog posts, that filenames should be kebab-case, that images go in src/assets/, and that it shouldn’t push without asking. It knows today’s date for the pubDate field. It knows the content pillars.

This is the difference between using Claude Code as a generic assistant and using it as a team member who’s read the project docs. The quality of output tracks directly to the quality of this file.

Brand docs: teaching Claude Code your voice

Four files in the brand/ directory define how content gets written:

  • voice-profile.md sets the tone: conversational, direct, confident, honest. Defines what the voice is and isn’t.
  • positioning.md frames the angle: practitioner-first, specific tooling, GTM-focused, honest about gaps.
  • audience.md describes who we’re writing for: GTM professionals at B2B SaaS companies who are experimenting with AI or curious about it.
  • writing-guide.md has the specific rules: no em dashes, no hype phrases, no generic intensifiers, no formulaic section closings, vary list structures. This file gets updated as new patterns emerge. It’s a living doc.

CLAUDE.md tells Claude Code to read these before writing any content. The brand docs don’t just inform the voice. They constrain it. Every rule in the writing guide exists because an AI-generated draft did something that read like a template. The guide is essentially a running list of “don’t do that again.”

Signal sync system

Two shell scripts pull signals from X and Reddit:

scripts/pull-x-signals.sh calls the X API with three searches targeting Claude Code + GTM, AI agents + B2B SaaS, and Claude Code + automation workflows. It captures tweet text, author info, and engagement metrics. Results append to drafts/x-signals.md with timestamps and deduplication.

scripts/pull-reddit-signals.sh does the same across six targeted subreddits (r/ClaudeAI, r/ClaudeCode, r/SaaS, r/AI_Agents, r/b2bmarketing, r/sales) plus two broad keyword searches. It filters by minimum score and excludes noisy subreddits (stock trading, coupons, crypto). Results go to drafts/reddit-signals.md.

A Claude Code command (/project:sync-signals) ties it together: run both scripts, read both signal files, read the content plan, analyze themes, and suggest updates. One command, two sources, a set of recommendations I can accept or ignore.

Running the sync looks like this:

Signal Sync

[X API]
Searching: Claude Code + GTM/Marketing ...
  Found 15 tweets.
Searching: AI Agents + B2B SaaS/GTM ...
  Found 14 tweets.
Searching: Claude Code + Agents/Automation/Workflow ...
  Found 14 tweets.

Done. 4 new signals written to drafts/x-signals.md

[Reddit]
Searching Reddit: r/ClaudeAI (GTM/marketing/workflow) ...
  Found 25 posts, filtering...
  Kept 13, filtered 12 (score < 2 or excluded subreddit).
Searching Reddit: r/ClaudeCode (GTM/marketing/workflow) ...
  Found 25 posts, filtering...
  Kept 9, filtered 16 (score < 2 or excluded subreddit).
Searching Reddit: r/SaaS (AI agents) ...
  Found 25 posts, filtering...
  Kept 7, filtered 18 (score < 2 or excluded subreddit).
Searching Reddit: r/AI_Agents (B2B/SaaS/GTM) ...
  Found 25 posts, filtering...
  Kept 15, filtered 10 (score < 2 or excluded subreddit).
Searching Reddit: r/b2bmarketing (AI/agents/automation) ...
  Found 25 posts, filtering...
  Kept 17, filtered 8 (score < 2 or excluded subreddit).
Searching Reddit: r/sales (AI agents/automation) ...
  Found 9 posts, filtering...
  Kept 7, filtered 2 (score < 2 or excluded subreddit).

Done. 75 new signals written to drafts/reddit-signals.md

The drafts directory

drafts/ sits outside src/ so Astro ignores it during builds. It holds:

  • content-plan.md, the 10-day editorial calendar mapped to the three pillars
  • x-signals.md and reddit-signals.md, the growing signal archives
  • In-progress post drafts and working screenshots

This is the workspace. Content starts here and moves to src/content/blog/ when it’s ready to publish.

drafts/                                src/content/blog/
├── Screenshot 2026-02-23 184557.jpg   ├── why-ai-agent-strategy.md
├── Screenshot 2026-02-23 213059.jpg   ├── perfect-lighthouse-score-astro-claude-code.md
├── Screenshot 2026-02-25 084950.jpg   ├── using-x-api-and-claude-code-to-build-a-content-plan.md
├── Screenshot 2026-02-25 090054.jpg   ├── signal-sync-is-not-a-system-yet.mdx
├── Screenshot 2026-02-25 090405.jpg   └── teardown-how-this-site-is-built.md
├── Screenshot 2026-02-25 092319.jpg
├── content-plan.md
├── reddit-signals.md
├── vision.md
└── x-signals.md

Left side: the workspace. Messy, timestamped screenshots, signal dumps, an unpublished draft. Right side: what’s live on the site. Five posts, clean filenames.

From signal to published post

A typical post goes like this:

  1. Run /project:sync-signals to pull fresh signals and get content plan recommendations
  2. Pick a topic from the plan based on what signals support it
  3. Claude Code reads the brand docs, then writes a draft directly in src/content/blog/
  4. I read it, ask for edits, tighten the voice
  5. npm run build to verify, then commit and push
  6. Vercel deploys

Signal sync to published post takes 30 to 60 minutes depending on how much I want to edit. The time isn’t in the writing. It’s in the editorial judgment: which topic, which angle, what to cut.

What’s still manual

The Claude Code layer automates signal collection and first-draft writing. It doesn’t automate editorial decisions. I still choose what to write, when to publish, and what angle to take. The signal system surfaces options. I pick.

That’s intentional for now. The content plan has 10 topics. Some are well-supported by signals. Others aren’t. A more mature system would score topics by signal strength and recommend the next post. That’s not built yet.

The other gap is feedback loops. PostHog will eventually show which posts get traffic and engagement. That data should feed back into the content plan alongside the signal data. Right now those are separate.

Seven npm dependencies. Two shell scripts. Four brand docs. One CLAUDE.md file. A drafts directory. A Vercel deploy pipeline.

The web and hosting layers are deliberately boring. The Claude Code content workflow is where the operational leverage lives: signal collection, content planning, voice-controlled drafting, and a pipeline that turns all of it into published posts.

Every post on this site, including this one, was written using the system it describes.