<!-- Markdown twin of https://pixelvault.dev/blog/nano-banana-image-hosting -->

[← Back to blog](/blog)

By [PixelVault](/about) July 14, 2026

# Generate images with Nano Banana, host them on PixelVault

You just generated a great image with Nano Banana — and now it's a link that expires in an hour, or a base64 blob with nowhere to live. This is the one-command loop that turns a prompt into a permanent CDN URL your coding agent can embed: generate with an AI model, host on PixelVault, done. (The post around it was agent-written too — but the art is the interesting part.)

![A coding agent generating a blog image with Nano Banana and hosting it on PixelVault for a permanent URL](https://img.pixelvault.dev/proj_mkoboesmx25d/img_o7q358uvddc9.png?w=1400&fmt=auto&q=auto)

The hero above was generated with Nano Banana (Google's Gemini image model) and hosted on PixelVault in one command — no download, no drag-and-drop. This is that loop.

Image models are genuinely good now. Ask **Nano Banana** — Google's Gemini image model — or GPT Image for a blog hero, a diagram, or a social card, and you get something you'd actually ship. Then the model hands you a link that **expires in about an hour** (OpenAI's image URLs do exactly this), or a base64 blob that's expensive to carry around and clumsy to save. The picture is great; it has nowhere durable to live.

So you break out of the flow: download the file, open a browser, drag it into a CMS or a GitHub issue, copy the URL back. Your coding agent generated the image in seconds; you spend the next ten minutes playing courier for it. That last mile — from "here's a nice image" to a URL you can embed — is the whole problem, and it's exactly where [hosting AI-generated images](/blog/host-ai-generated-images) usually falls down.

## The loop, closed

Give the agent one more tool — image hosting that returns a permanent URL — and generate-and-host runs end to end without you:

-   **Generate.** The agent calls an image model — [GPT Image](/blog/host-ai-generated-images), or Google's Nano Banana (`gemini-3.1-flash-image`) / Nano Banana Pro (`gemini-3-pro-image`) — for the hero and any inline art.
-   **Host.** It hands the result to PixelVault and gets back `https://img.pixelvault.dev/…`, a permanent, globally-cached URL that won't rot.
-   **Embed.** It drops that URL into the Markdown and the `og:image` tag, and moves on — and yes, it can write the surrounding post too.

No context switch, no browser, no manual upload. The hero at the top of this post was made exactly this way — Nano Banana → PixelVault, one command.

## The prompt lives in version control

Image models are non-deterministic — run the same prompt twice and you get two different pictures. So the trick to making this _repeatable_ is to treat the prompt as source. We keep a tiny manifest, one entry per post, with the prompt, the alt text, and the URL the tooling fills in:

// apps/web/src/data/heroes.json — the prompt lives in version control,  
// so the art is reproducible and the URL is filled in for you.  
{  
  "nano-banana-image-hosting": {  
    "prompt": "Editorial blog hero, flat vector... no text. 16:9.",  
    "alt": "A coding agent generating an image with Nano Banana and hosting it on PixelVault",  
    "url": ""  
  }  
}

Now regenerating art is one command, and anyone — human or agent — can reproduce or tweak a hero without hunting for the original prompt:

\# Generate the hero with Nano Banana, host it on PixelVault:  
npm run gen-hero -- nano-banana-image-hosting  
  
\# → hosted, and the permanent URL is written back into the manifest:  
\# https://img.pixelvault.dev/<project>/<image>.png

## The open-source skill that does it

Behind that command is a small, open-source skill — [pixelvault-generate](https://github.com/pixelvault-dev/skill) — that does one thing: take a prompt, generate the image through [OpenRouter](https://openrouter.ai) (point it at whichever image model you like), then host the result on PixelVault and hand back the permanent URL. It's a `SKILL.md` plus a few lines of shell, so any agent that reads a skill file can run it — and it drops into any project. The hero on this page was made exactly this way with `google/gemini-3.1-flash-image`; swap the slug for `google/gemini-3-pro-image` and you're on Nano Banana Pro instead.

If your agent already speaks [MCP](/blog/mcp-image-hosting), it doesn't even need the script — PixelVault's `upload_image` tool takes a `source_url`, so the agent can hand it the model's temporary link and get a permanent one back directly. Either way, the instruction to the agent is a single rule you drop in your repo:

\# CLAUDE.md / AGENTS.md — one rule, and any agent runs the whole loop  
When a post needs a hero, add a prompt to heroes.json,  
run \`npm run gen-hero -- <slug>\`, then reference the hosted URL.  
Never paste base64 or a temporary model URL into a post.

## One upload, every size

A hero image needs to be several things at once: a crisp picture in the article, a 1200×630 card for social previews, a lightweight thumbnail in a list. You don't generate those separately. PixelVault does transforms from the URL, so one upload becomes every size by adding query params — `?w=1200&h=630&fmt=auto` for the OG card, `?w=700&fmt=auto&q=auto` for the body. The original PNG on this post is over a megabyte; the card your social feed actually loads is a 73 KB JPEG, chosen automatically. The agent uploads once; the sizes take care of themselves.

## Where the keys live

Image generation is an _authoring-time_ job, not something your deployed site does. The OpenRouter key and your PixelVault key sit in a local `.env` the tooling reads when you run the command — they never ship to production, and the published page only ever references the finished `img.pixelvault.dev` URL. Your build stays fast, deterministic, and secret-free.

## A note on ownership — and what's next

Right now your images live in PixelVault's storage on Cloudflare's edge, served from a zero-egress CDN, so a post that goes viral doesn't hand you a bandwidth bill. **Bring-your-own-key (BYOK) is coming with the paid plans** — alongside custom domains and unlimited private links — so you can point PixelVault at your own R2 or S3 bucket, own the bytes, and keep the same one-call hosting and transforms. It's on the roadmap, not shipped yet; we'll say so plainly here when it lands.

## Try the loop

Give your agent a hosting tool and the courier work disappears. Grab a key by [registering with a single API call](/docs), connect the [MCP server](/blog/mcp-image-hosting) or drop in the skill, and the next post your agent writes can illustrate and publish itself. The free tier includes 200 MB storage, 500 uploads/month, and 1 GB bandwidth — no credit card. Paid plans start at [$9/month](/pricing).

[Read the docs →](/docs)
