Primary keyword: convert blog to Instagram carousel · Long-tail: Nano Banana Instagram carousel, OpenRouter image API Instagram, AI HTML Instagram slides, AI React code generator for IG posts, blog list to carousel admin
You can write a hundred solid blogs and still lose the week to Canva.
That is the real bottleneck for developer sites with a big archive. The writing is done. The distribution is not. Instagram wants short hooks, dense slides, and a consistent visual system. Your markdown folder wants H2s, code blocks, and 2,000-word essays. Bridging those two formats by hand does not scale.
This post is how we turned that gap into an admin workflow: load the blog list into a table, pick a row, then generate a carousel with either Google Nano Banana images through OpenRouter, AI HTML slides you export locally, or the same mental model as an AI React code generator when you want component-based slides instead of PNGs.
The live tool sits at /ig-post-creator. The ideas below are the design behind it, so you can rebuild the same pattern on your own stack.
The problem is not "more content"
We already publish from a static markdown catalog under blogs-content/. Each file has title, slug, description, tags, and a body with ## sections. That same catalog powers /blog, /articles.json, and the blog sitemap.
What we did not have was a second view of that catalog: one built for Instagram production.
Without that view, every post becomes a one-off design job. You open the essay, invent a carousel structure, rewrite the copy for mobile, pick colors, export slides, and forget which blogs you already turned into posts. After twenty articles the system collapses into a spreadsheet you never update.
So the product is not "an image model." The product is an admin table of blogs with a generate button.
Step 1: Build the admin table from your blog list
Start from the same source of truth you already trust for SEO.
For each markdown blog, derive a row:
| Column | Where it comes from |
|---|---|
| Title / hook | Blog title, shortened for IG |
| Category | First tag, or a simple heuristic (AI, SaaS, Blog) |
| Sections | Every ## heading in the body |
| Slide count | One slide per H2 (plus cover/CTA if you want) |
| Status | Idea vs Generated (localStorage is enough at first) |
| Blog URL | /blogs/{slug} |
On iHateReading, loadBlogCarouselIdeas() walks the newest markdown posts, strips frontmatter, splits on ##, and returns JSON the admin UI can filter. The page loads that list server-side, then refreshes from /api/instagram/blog-carousel-ideas so the table stays current when new blogs land.
That mapping rule matters more than the UI chrome:
One H2 ≈ one carousel slide.
Long essays become carousels without a second outline. If a post has six sections, you get six teaching slides. If it has three, you get three. You stop inventing structure every time.
If you are still building the content engine that feeds this table, the pipeline in How we write 100 SEO blogs a day for under $10 is the upstream half. This post is the downstream half: archive → Instagram.
Step 2: Give every row two output modes
Once a blog is selected, the admin should ask one question: how do you want the slides rendered?
Mode A — AI images (Nano Banana via OpenRouter)
Google's image models ship under the Nano Banana family. Nano Banana 2 is Gemini 3.1 Flash Image: fast, good text rendering, native aspect ratios. OpenRouter exposes those models through a dedicated Image API at POST /api/v1/images, so you keep one API key and can swap models later.
Our path looks like this:
- Read the full blog markdown for the selected slug.
- Ask a planning model (chat completions, JSON mode) to turn each section into an IG-native slide plan: short headline, 2–3 word bullets, visual direction. No URLs on the image — link goes in the caption.
- For each slide, call OpenRouter images with a 4:5 prompt (
1080 × 1350). - Preview the carousel in the admin, then download the PNGs.
In code, the image call is boring on purpose:
const response = await fetch("https://openrouter.ai/api/v1/images", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`,
"Content-Type": "application/json",
"HTTP-Referer": "https://ihatereading.in/ig-post-creator",
"X-Title": "iHateReading IG Post Creator",
},
body: JSON.stringify({
model: "google/gemini-3.1-flash-lite-image", // Nano Banana 2 Lite
prompt: slidePrompt,
aspect_ratio: "4:5",
}),
});Use Lite when you are batching a long list. Step up to Flash or Pro when a single carousel needs sharper type. Google's own prompting guide for Nano Banana is worth reading once so you stop writing vague "make a nice carousel" prompts.
Mode B — AI HTML slides (cheap, local export)
Image APIs cost money and take time. For drafts, or for days when you only need structure, generate HTML slides instead.
OpenRouter chat returns JSON slides with layouts (cover, explain, steps, code, cta). The admin renders those as React DOM nodes styled for Instagram. Export uses html-to-image (or any DOM-to-PNG path) so you still leave with files you can post.
This mode is the same idea as AI HTML generators: the model writes structure and copy, the browser paints pixels. You keep brand CSS in your app instead of hoping the image model remembers your fonts.
Mode C — AI React code generator as the slide engine
If you already ship an AI React code generator — prompt in, Tailwind component out — you can treat each carousel slide as a component, not a bitmap.
That path looks like:
- Prompt: "Return a single React + Tailwind slide component for this H2 and excerpt. Fixed 1080×1350 frame. No external images."
- Preview the component in an iframe or React Live sandbox.
- Screenshot or rasterize for Instagram, or keep the component library for Stories / web embeds later.
We wrote about building that generator with Next.js and the Vercel AI SDK in AI React Tailwind Code Generator App. For IG, you do not need a full IDE product. You need a constrained prompt, a fixed canvas size, and a download step. Same architecture, narrower job.
Pick the mode per row:
- Nano Banana images when the post needs a strong visual brand.
- HTML slides when you want speed and zero image spend.
- React components when you want reusable slide kits across channels.
Step 3: Wire OpenRouter once, reuse it everywhere
Do not scatter provider SDKs across the admin.
One key (OPENROUTER_API_KEY), two endpoints:
https://openrouter.ai/api/v1/chat/completionsfor planning copy and HTML slide JSONhttps://openrouter.ai/api/v1/imagesfor Nano Banana / Gemini image models
That split matches how OpenRouter announced the unified Image API: chat for text, images for pixels. It also matches how we already use OpenRouter elsewhere — for example in the AI automated Reddit trend scraper — so ops stays one billing page and one key rotation.
Practical rules that saved us retries:
- Keep image generation on the server. Keys never reach the browser.
- Cap slides (six to eight) so a bad prompt cannot burn a full day of credits.
- Store "Generated" status in localStorage first. Promote to a real DB only when multiple people share the queue.
- Soft CTA only on the last slide. Every earlier slide should teach.
The carousel brief that actually works on Instagram
Whether you generate images, HTML, or React, the content brief is the same.
For each section of the blog:
- Hook line — under ~8 words, readable at thumb size
- Two or three bullets — facts, not paragraphs
- One visual cue — sketch panel, code card, or product UI
- No URLs on the slide — put the link in the caption / bio
Then close with a soft CTA: "Full write-up on iHateReading" beats "BUY NOW" for a developer audience.
If the source post is distribution-heavy — directories, launches, free traffic — pull hooks from pieces like How to Get Free Traffic to Your Website in 2026 or the 393 SaaS directories essay. The admin table makes that reuse mechanical: pick the row, generate, post.
For the agent-tooling side of wiring models and tools cleanly, the AI Agent Developer Roadmap still applies. This admin is a thin agent: tools are list_blogs, plan_slides, render_image, export_png.
What we are not automating yet
Honest scope:
- We do not auto-post to Instagram from this admin. Publishing still needs a human eye.
- We do not claim Nano Banana replaces a designer for brand campaigns. It replaces the blank-canvas hour for educational carousels.
- We do not generate captions that sound like ads. The blog already has the voice; the carousel compresses it.
The win is throughput. A catalog of a hundred posts becomes a queue you can clear in batches: ten carousels a week from essays you already wrote, without opening Canva ten times.
Build order if you are starting from zero
- Static blog list you can read from disk or an API (markdown is enough).
- Admin table with search, category, and Generated status.
- OpenRouter chat that returns slide JSON from one blog body.
- HTML preview +
html-to-imageexport so you can ship before paying for images. - OpenRouter Image API + Nano Banana for the rows that need real artwork.
- Optional React generator if you want component slides for web and IG both.
If you want the monthly roundup of tools and posts in this lane, the iHateReading Magazine is the digest. If you want the creator itself, open /ig-post-creator and start from the Blogs tab.
More to come as we add caption drafts and a shared Generated queue.
Cheers, ShreyZ