<img> tag. These are scenes and backgrounds (heroes, cards, tiles), not runtime user-triggered generation.
Placing a generated image
Write each URL into its own<img> as a string literal so the visual editor’s image picker can find (and let the user replace) it:
consts or a .map() data array — <img src={heroUrl} /> is invisible to the picker. For a grid, write each tile as its own literal <img>.
Models & prompting
fast(default, ~5s) — everywhere. Keep prompts plain; subjective adjectives don’t help and rendered text on signs/menus is unreliable.quality(~45s) — only the page’s single large hero, when render quality materially matters. It rewards richer, art-direction language (“cinematic”, “shallow depth of field”).- Fire a page’s image calls in one parallel step — eight fast images is ~5s wall-clock.
- Each prompt is self-contained: brief it like a photographer — subject + scene + mood + medium + lighting. Headlines and chrome go in JSX, never the prompt. Repeat lighting/medium adjectives across a multi-image page for coherence.
- Aspect ratio —
16:9/3:2heroes and banners,4:3/1:1cards and portraits,9:16/3:4phone mockups.
Hero with overlaid text
A dark bottom gradient with white text works for almost any hero:bg-gradient-to-r / -to-l), and switch to dark text on pale shots. The default JSX above is the safe fallback.
Gotchas
- Every generated image must be a literal
<img>to stay editable in the visual editor. - Reserve
qualityfor the primary hero — ~9× slower and several times more expensive. - Edit vs regenerate: edit to change one thing (“make it sunset”) keeping the composition (aspect ratio is preserved); regenerate when subject/scene changes fundamentally; adjust JSX when only layout is off.
- On a generation failure, drop a labeled placeholder
<div>matching the aspect ratio, not a broken<img>. - For runtime user uploads instead, see File uploads.