
Building an AI-Powered Image Pipeline for My Blog with Claude Code
How I used Claude Code on the web to design and implement automatic AI-generated featured images for my Nuxt blog, complete with Cloudflare Pages integration.
Building an AI-Powered Image Pipeline for My Blog with Claude Code
I've been thinking about what my blog was missing. The code was solid - good SEO, dark mode support, nice typography, responsive design. But something felt off when I looked at the blog listing page. It was... plain. Just text on text.
Then it hit me: featured images.
Every successful blog has them. They make posts more engaging, dramatically improve social media sharing, and give readers a visual hook before diving into content. But here's the thing - as a developer, I've always found creating these images to be a tedious interruption to my writing flow. I'd rather be coding than wrestling with image editors.
So I set out to build something that would solve this once and for all.
What I Wanted
My requirements were clear:
- Generate unique, visually appealing hero images for each blog post
- Zero manual image creation effort
- Automatic generation in my CI/CD pipeline
- Free (I'm not paying for yet another API subscription)
- Images should actually reflect the post content, not be generic stock photos
The Architecture
After some experimentation with Claude Code on the web, I landed on a hybrid approach that separates two concerns:
Layer 1: Programmatic OG Images
Using nuxt-og-image with Satori, I set up text-based social cards that are generated automatically. These ensure every post always has a professional sharing image - even if the AI image generation fails.
Layer 2: AI-Generated Hero Images
This is where it gets interesting. The pipeline works in two stages:
- Prompt Generation: Claude CLI analyzes the blog post content and generates an optimized image prompt
- Image Generation: A free service (Pollinations.ai) turns that prompt into an actual image
The key insight was separating these concerns. Claude is great at understanding content and crafting prompts. Specialized image models are great at generating visuals. Why not use both?
The Implementation
Schema Updates
First, I added new fields to my Nuxt Content blog schema:
schema: z.object({
published: z.boolean(),
created_at: z.date(),
tags: z.array(z.string()).optional(),
image: z.string().optional(), // Hero image path
imageAlt: z.string().optional(), // Accessibility
imagePrompt: z.string().optional(), // Prompt for regeneration
})
That imagePrompt field turned out to be crucial - storing the prompt makes regeneration trivial and provides transparency into how each image was created.
The Generation Script
The TypeScript script handles the full workflow:
// For each post needing an image
if (post.existingPrompt) {
// Use saved prompt from frontmatter
prompt = post.existingPrompt
} else {
// Generate new prompt with Claude CLI
prompt = generateImagePrompt(post)
}
// Fetch from free image API
const imagePath = await generateImage(prompt, post.slug)
// Update the markdown frontmatter
updateFrontmatter(post.filePath, imagePath, prompt, altText)
Crafting Good Prompts
The quality of generated images depends heavily on the prompts. I developed a system prompt that ensures consistent, on-brand imagery:
## Style Guidelines
- Aesthetic: Modern, clean, slightly futuristic
- Colors: Deep blues, purples, teals with accent colors
- Mood: Professional yet inspiring
## What Works Well
- Abstract geometric patterns representing concepts
- Flowing light trails, data streams, neural pathways
- Ethereal landscapes that evoke the topic metaphorically
## What to Avoid
- Literal depictions (no laptops, code screens)
- Stock photo clichés (handshakes, lightbulbs)
- Faces or human figures
This ensures every image feels cohesive with the blog's visual identity while still being unique to each post's content.
CI/CD Integration
Here's where I ran into my first real challenge. I wanted images generated during Cloudflare Pages deployment, not committed to the repository. But my initial approach didn't work.
The Problem
Cloudflare Pages was running nuxt generate directly, which bypasses npm lifecycle hooks. My pregenerate script never executed.
The Solution
I created an explicit build script:
{
"scripts": {
"build:cloudflare": "npx tsx scripts/generate-blog-images.ts --ci && nuxt generate"
}
}
The --ci flag configures the script for CI environments:
- Uses existing prompts only (no Claude CLI required)
- Never fails the build (graceful degradation)
- Processes all posts with saved prompts
The deployment flow now looks like this:
Push to main
↓
Cloudflare triggers build:cloudflare
↓
Script fetches images from Pollinations.ai
↓
Nuxt generates site with images
↓
Deploy!
Local Development Workflow
For local development, I added a pre-push git hook that:
- Detects if any blog posts are being pushed
- Checks for missing images
- Generates them automatically
- Prompts me to commit before pushing
This means I can focus on writing. The tooling handles the rest.
Results
The system now handles the entire image workflow automatically:
| Scenario | What Happens |
|---|---|
New post with imagePrompt | CI generates image automatically |
| New post without prompt | Claude CLI generates prompt locally first |
| Existing post | Skipped (already has image) |
| Regenerate needed | Remove image field, run script |
What I Learned
Separation of Concerns Pays Off
Using Claude for prompt generation and Pollinations.ai for image generation made the system both flexible and free. Each tool does what it's best at.
Store Your Prompts
Keeping prompts in the frontmatter has been invaluable. I can see exactly what generated each image, tweak prompts if needed, and regenerate consistently.
Graceful Degradation Matters
The site works perfectly fine without hero images - they're an enhancement, not a requirement. If image generation fails, the programmatic OG images still provide good social sharing previews.
CI Environments Are Different
Things that work locally might not work in CI. The --ci mode that uses pre-generated prompts (instead of requiring Claude CLI) was essential for making this production-ready.
Try It Yourself
If you want to implement something similar:
- Start with the schema - Add
imageandimagePromptfields to your content model - Create a generation script - Use any image API (Pollinations.ai is free)
- Store prompts - Keep them in your content for reproducibility
- Integrate with CI - Run generation before your static site build
- Add fallbacks - Programmatic OG images ensure you always have something
Conclusion
What started as "my blog needs images" became a fun exploration of how to automate creative tasks in development workflows. The combination of Claude's reasoning capabilities with specialized image generation creates a powerful, cost-free pipeline.
The best part? Once it's set up, I don't think about it anymore. I write a post, add a prompt (or let Claude generate one locally), push, and my blog has a beautiful hero image. That's exactly the kind of developer experience I was after.
Now I can focus on what actually matters: the content itself.
