Hero image for "Building an AI-Powered Image Pipeline for My Blog with Claude Code": Abstract digital assembly line with glowing nodes transforming text into vibrant images, streams of
7 min read

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:

  1. Prompt Generation: Claude CLI analyzes the blog post content and generates an optimized image prompt
  2. 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:

  1. Detects if any blog posts are being pushed
  2. Checks for missing images
  3. Generates them automatically
  4. 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:

ScenarioWhat Happens
New post with imagePromptCI generates image automatically
New post without promptClaude CLI generates prompt locally first
Existing postSkipped (already has image)
Regenerate neededRemove 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:

  1. Start with the schema - Add image and imagePrompt fields to your content model
  2. Create a generation script - Use any image API (Pollinations.ai is free)
  3. Store prompts - Keep them in your content for reproducibility
  4. Integrate with CI - Run generation before your static site build
  5. 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.