How I wire up Ideogram and Claude Code to generate every hero image on this site

8 min read

Cover for How I wire up Ideogram and Claude Code to generate every hero image on this site

đź”— Some links in this post may be affiliate links - I may earn a small commission if you sign up, at no extra cost to you. I only list tools I genuinely use or thoroughly vet.


Every blog post I publish needs a hero image. Before I sorted out a proper workflow for this, it was a 20-minute detour every time: open a browser tab, describe what I want to an AI image tool, download the result, check the dimensions, run it through an optimizer, drop it in the right folder.

It was fine once. By the fifteenth post it was genuinely annoying.

Now I generate images from the same terminal window I use to write, edit, and deploy the site. Here is how that setup works, what the image skill actually does, and where things broke before they worked properly.

What Claude Code skills are and why they matter here

Claude Code supports skills, which are loaded instruction sets that tell Claude how to approach a specific class of task. Think of them as persistent context for a workflow, the kind of thing you would otherwise explain from scratch every session.

The image skill is one of these. When I invoke /image, Claude reads any existing product marketing context I have set up for the site (mine lives at .agents/product-marketing-context.md), then works through a structured set of questions before generating anything: what type of image, what placement, what dimensions, whether I have API keys configured for specific tools.

It covers several generation models: Gemini, Flux, Ideogram, and GPT Image (the current OpenAI image model, which replaced the deprecated DALL-E 3). Each one has a different strength. The skill helps pick the right one for the job rather than defaulting to whatever happens to be popular right now. I can still override the model if I want, but the skill’s guidance saves a lot of trial and error.

Why Ideogram for blog headers

I landed on Ideogram for a specific reason: it handles text in images better than anything else I have tested.

Not every hero image I generate needs text in it, but most do, and not all models handle text well. Gemini is good all-around. Ideogram is what I reach for when I need a generated image with a clean headline or label baked in. The image skill also favors Ideogram for blog headers because of this strength, which is why it is the default model for the /image command when I specify that use case.

For blog headers at 1600x900, Ideogram produces consistently usable results with minimal prompt iteration. That matters more to me than having the most artistic possible output. Artistic output that takes eight attempts to get right is not a productivity win.

What the workflow looks like in practice

The setup requires an Ideogram API key, which comes from their developer portal. Once that is in my environment, the skill can call the API directly from inside Claude Code.

In practice it looks like this:

  1. Finish writing the post
  2. Open Claude Code in the same terminal session (it is already open)
  3. Run /image and describe what I want: the topic of the post, the visual mood, whether I need any text included
  4. Claude confirms the parameters, structures a prompt, and calls the Ideogram API
  5. The image lands in the post folder, named heroImage.png

The whole thing usually takes a couple of minutes, most of that being the Ideogram generation response time. The prompt structuring step is what I used to do manually and now I just review it rather than write from scratch every time.

Where it broke

The first issue was aspect ratio. Blog hero images are usually 16:9 ratio. The first few generations came back at 1:1, which is Ideogram’s default square output. The skill covers this in its documentation, but I had not been explicit enough in my initial requests about what dimensions I needed.

Once I started stating the target dimensions or aspect ratio clearly in every request, that stopped happening.

The second issue was visual consistency. The first few hero images generated fine individually, but they looked like they came from different sites. Different color treatments, different moods, no coherent visual language across posts.

I fixed it by writing a short style brief into the product marketing context file. Now every image generation starts from that baseline, and the results are noticeably more coherent post to post. It still requires a judgment call on each individual image, but the floor is higher.

What I would do differently

Write the style brief before generating the first image, not after the first five. The earlier that baseline exists in the product marketing context file, the more consistent the output is from day one. I did it the wrong way around and spent several sessions correcting the drift.

Instead of trying out multiple image runs until I got something I liked, I should have asked Claude to generate multiple options in one go and then let me pick the text and image design concept I wanted to go with first. That would have been more efficient than running the same prompt several times and hoping for a good result. I updated the workflow to reflect this after the fact, but it would have been better to start that way.

For blog hero images that need to look professional without briefing a designer, it does what I need. The API is credit-based, so you only pay for what you generate, which keeps costs predictable at low volume.

If you want to try it: Ideogram.

How a short style brief fixed the consistency problem

Asked Claude to update the product marketing context file with a style brief for the site, which now serves as a baseline for every image generation. This was a big boost to visual consistency across posts and saved a lot of time in prompt iteration.

Here’s the key part of that brief, which is now in my .agents/product-marketing-context.md and gets read by the image skill every time. It contains specific instructions on how I want Claude Code to get what API key it needs:

### Model selection
- **Ideogram V3** — use when the image needs text baked in (most blog heroes). Sharpest text rendering.
- **GPT Image (gpt-image-2)** — use for artistic/abstract heroes with no or minimal text.
- Default to Ideogram V3 unless the user specifies otherwise.

### Dimensions & format
- Ideogram V3: aspect ratio `16x9`
- GPT Image: size `1536x1024`
- Format: PNG
- Filename: `heroImage.png` — if it already exists, save as `heroImage-rev1.png`, `heroImage-rev2.png`, etc.

### API keys & runtime
- User must set environment keys : `OPENAI_API_KEY`, `IDEOGRAM_API_KEY`, `GEMINI_API_KEY` using process below.

On Mac:

export OPENAI_API_KEY="your_api_key_here"
export IDEOGRAM_API_KEY="your_api_key_here"
export GEMINI_API_KEY="your_api_key_here"

Restart the terminal or run `source ~/.zshrc` (or ~/.bashrc)

Before making any API call, verify the required key is set as shown here for OPENAI_API_KEY (same process for other API keys):

if [ -z "$OPENAI_API_KEY" ]; then
  echo "ERROR: OPENAI_API_KEY is not set. Please export it in your shell profile."
  exit 1
fi

If the key is missing, stop and tell the user to set it using the instructions above.

On Windows:

setx OPENAI_API_KEY "your_api_key_here"
setx IDEOGRAM_API_KEY "your_api_key_here"
setx GEMINI_API_KEY "your_api_key_here"

Restart the terminal so the new variables are loaded.

Before making any API call, verify the required key is set as shown here for OPENAI_API_KEY (same process for other API keys):

if (-not $env:OPENAI_API_KEY) {
  Write-Host "ERROR: OPENAI_API_KEY is not set. Please set it with setx and restart your terminal."
  exit 1
}

If the key is missing, stop and tell the user to set it using the instructions above.

CAUTION

Be extra careful with your API keys. The steps above keep your keys out of your code and project files, which is the important part, but they don’t guarantee a key can never be exposed. Treat any API key that shows up in terminal output, a log file, or a chat message as potentially leaked. This matters especially with AI tools: with Claude Cowork skills that use API keys, the messages you see may not even reflect that your key has been picked up by a background step and sent to Anthropic’s servers as part of a request to the model.

Whilst there are more secure methods to handle API keys, it’s beyond the scope of this blog post. As a minimum, set up a separate API key used only for this skill, put a spend limit on it so a mistake can’t run up a large bill, rotate your keys periodically, and revoke a key straight away if you suspect it has been exposed.

I liked how the skill was written to allow an override of the default model choice and behaviour through the product marketing context file, clever.

The tool stack for this workflow

Three things working together:

  • Claude Code: the terminal-based AI coding tool where the skill runs. This is where I do most of my site work anyway, so the image generation fits into the same session rather than requiring a context switch.
  • Image skill: the skill that handles model selection, prompt structure, dimension guidance, and the Ideogram API call. Open source, installable into any Claude Code setup.
  • Ideogram: the image generation model. Credit-based API, good text rendering, consistently usable output at blog header dimensions.

That is the whole stack. There is nothing exotic about it.