# Generate images for a Typeroll site (local lab → media library) Source: [Generate images for a Typeroll site (local lab → media library)](https://typeroll.com/docs/skills/tr-imagegen/) > Use when the user wants to generate images for a Typeroll site with AI models (Gemini, OpenAI, Higgsfield) — hero images, illustrations, section backgrounds, og-images. Triggers on "generera bilder", "generate images", "skapa en hero-bild", "AI-bilder", "bildgenerering", or when a brief calls for imagery that doesn't exist in assets/. Covers the local lab loop (generate → review → pick) and uploading winners to the Typeroll media library. This is the `tr-imagegen` recipe exactly as the Typeroll MCP server gives it to agents through `list_skills` and `read_skill`. See [Skills and recipes](https://typeroll.com/docs/skills/overview/) for how agents load recipes. Image generation runs **locally** in the site workdir — provider API keys live in the folder’s `.env`, candidates land in `images/lab/`, and only the picked winners are uploaded to the Typeroll media library via the regular media tools (see `tr-images` for the upload/variants half). Why local: you can look at the candidates (Read the files), iterate on prompts cheaply, and never ship a key or a reject anywhere. ## Folder convention ```plaintext / ├── .env # provider keys — GITIGNORED, never committed ├── prompts/ │ └── image-style.md # the site's image style profile (see below) └── images/ └── lab/ # generated candidates — gitignored, disposable ``` `.env` keys (only the ones the user has — check before assuming): ```plaintext GEMINI_API_KEY=... OPENAI_API_KEY=... ``` (Higgsfield needs no key here — it connects as an MCP server, see below.) Load them per-command (`source .env` doesn’t persist between Bash calls): ```bash export $(grep -v '^#' .env | xargs) # prepend to each generation command ``` ## The style profile — prompts/image-style.md Every site gets ONE style profile that you **prepend to every image prompt**. This is what keeps 20 images generated across 5 sessions looking like one site. Derive it from `assets/brand.md` + the brief if it doesn’t exist yet, and confirm it with the user before generating at scale. Keep it short (5–10 lines): art direction, palette, mood, photography vs illustration, what to avoid. Example shape: ```markdown # Bildstil — Varm, folklig illustration med mjuka rundade former. Platt 2D med subtila skuggor — ingen 3D, ingen fotorealism. Palett: kobolt #1F4FB8, sol #FFC83D, grädde #FFF8EC; accenter sparsamt. Människor: enkla, inkluderande, glada — inga karikatyrer. Undvik: stockfoto-känsla, text i bilden, logotyper, watermarks. ``` ## Generate candidates Name candidates descriptively: `images/lab/--.png`. Generate 3–6 candidates per slot (mix models when several keys exist), then **Read the files to actually look at them** before showing the user your shortlist. ### Gemini (gemini-2.5-flash-image) ```bash curl -s "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-image:generateContent" \ -H "x-goog-api-key: $GEMINI_API_KEY" -H 'Content-Type: application/json' \ -d '{ "contents": [{"parts": [{"text": "