Building a Multi-Site Automated Technical Blog System with Session-Based Post Generation
What Was Done
Created an automated technical blogging infrastructure that captures development work across four domains (tech.queenofsandiego.com, tech.dangerouscentaur.com, tech.sailjada.com, tech.burialsatseasandiego.com) and generates granular technical posts from Claude Code session transcripts. The system automatically deploys blog posts to S3/CloudFront as development work completes, with integration into the Ship's Papers navigation menu.
Technical Architecture
The solution consists of three core components:
- Session Capture Hook (
/Users/cb/.claude/hooks/tech_blog_stop.sh): Executes when a Claude Code session ends, extracting the JSONL session transcript - Blog Generator (
/Users/cb/Documents/repos/tools/tech_blog_generator.py): Parses session transcripts, identifies granular work items, generates structured HTML posts with technical detail - Infrastructure Initialization (
/Users/cb/Documents/repos/tools/tech_blog_init.py): Provisions S3 buckets, CloudFront distributions, ACM certificates, and DNS records for each tech blog domain
Infrastructure Setup Details
Domain Strategy: Each site gets a dedicated subdomain under its primary domain:
tech.queenofsandiego.com→ Route53 in primary accounttech.sailjada.com→ Route53 in primary account (wildcard*.sailjada.comcert available)tech.dangerouscentaur.com→ Namecheap DNS, CNAME to existing CloudFront distributionE2Q4UU71SRNTMB(bucket:dc-sites)tech.burialsatseasandiego.com→ GoDaddy DNS (requires API-based validation)
S3 & CloudFront Pattern: Each blog site uses a dedicated S3 bucket named {site}-tech-blog (e.g., qos-tech-blog, jada-tech-blog) with CloudFront distribution for caching and HTTPS. Static HTML posts are indexed via a generated index.html that lists all articles by date.
SSL/TLS Certificates:
- queenofsandiego.com and sailjada.com: Wildcard ACM certificates already existed (
*.queenofsandiego.com,*.sailjada.com), enabling direct use fortech.*subdomains - dangerouscentaur.com: Reused existing wildcard CloudFront distribution with
dc-sitesS3 origin via CNAME at Namecheap - burialsatseasandiego.com: Created new ACM certificate with DNS validation via GoDaddy API, adding CNAME record to
_***.acm-validations.aws.`for domain ownership proof
Session Transcript Processing
Claude Code stores session transcripts as JSONL files in /Users/cb/.claude/projects/-Users-cb-Documents-repos/. Each line is a JSON object representing a message or tool call. The generator extracts:
- Tool uses: File reads, writes, edits with exact paths and purposes
- Commands executed: AWS CLI, Python scripts, file operations
- Decision points: Why certain architectural choices were made (e.g., reusing existing CF dist vs. creating new one)
- Infrastructure changes: S3, CloudFront, Route53, ACM operations with resource IDs
- Timestamps & sequencing: Chronological ordering of work items for narrative flow
The generator filters out sensitive data (credentials, API keys, auth tokens) and sensitive personal information before publishing.
Blog Post Generation
Each generated post includes:
- Granular work breakdown: Individual file edits, function changes, infrastructure updates listed with exact paths and purposes
- Decision rationale: Why infrastructure choices were made (e.g., "Reused existing dangerouscentaur CloudFront distribution to avoid unnecessary AWS resources and billing")
- Technical depth: CloudFront distribution IDs, S3 bucket names, Route53 zone IDs, command examples for debugging
- Architecture patterns: Multi-site S3/CloudFront pattern, session-based automation, DNS provider abstraction (Route53 vs. GoDaddy vs. Namecheap)
- HTML structure: Semantic tags (
<h2>,<h3>,<ul>,<code>) for readability and SEO
Navigation Integration
Updated /Users/cb/Documents/repos/sites/queenofsandiego.com/index.html Ship's Papers dropdown menu to include link to tech.queenofsandiego.com. Similar navigation updates applied to other sites after their tech blogs go live.
Key Architectural Decisions
- Automated capture on session end: The Stop hook triggers immediately when a Claude Code session completes, eliminating manual post creation and ensuring no work is missed
- JSONL transcript parsing: Claude Code's native JSONL format is parsed directly—no additional instrumentation needed, works with all existing sessions
- Per-domain S3 buckets: Separate buckets for each site enable granular access control, CloudFront invalidation, and cost tracking per business entity
- DNS provider abstraction: System detects existing DNS provider per domain (Route53 vs. Namecheap vs. GoDaddy) and uses appropriate API—no forced provider migration
- Static HTML posts: No database or backend—posts are static HTML deployed to S3, cached by CloudFront, minimizing operational complexity and cost
- Index generation:
index.htmlon each blog is auto-generated with post summaries, dates, and links—stays current as new posts deploy
Deployment Workflow
- Developer completes work in Claude Code session
- Session ends → Stop hook executes → extracts JSONL transcript
- Blog generator parses transcript → identifies work items → generates HTML post
- Post uploaded to site's S3 bucket (e.g.,
qos-tech-blog) - Index.html regenerated with new post entry
- CloudFront invalidated to clear cache → new content live within seconds
- Post visible on tech blog; Ship's Papers menu links to it
What's Next
Future enhancements: