sas.vc · utility

Open Graph Image Generator

Generates the picture people see before they click. The model draws a wordless image; the wording is composited here, in the site's own type and colours.

Manual — read this first
What this does, and why it works this way

Each entry sends a prompt to OpenAI's gpt-image-1, receives a wordless image, crops it to the 1200 × 630 Open Graph shape, and draws the wording on top using Fraunces and Newsreader against the section colour.

The model is never asked to render text. Badly formed lettering is the most reliable giveaway that an image was generated, more so than hands. Compositing the type here gives crisp text, exact brand colours, and — the practical benefit — lets you rewrite the wording as many times as you like without paying for another image.

For the same reason the prompts avoid human faces and hands wherever the idea survives without them. Where a person genuinely helps, the prompt asks for them distant, back-turned or silhouetted.

Setting it up

One file. og.php serves this page on a GET and handles image generation on a POST to og.php?a=gen, reading the key from secrets.php on the server. The key never reaches the browser.

Add to /private/og-config.php — a NEW file, not secrets.php. secrets.php is a live POST endpoint that exits on a GET, so including it from a page stops the page dead. Config meant to be included must be inert.

$OPENAI_API_KEY = 'sk-...';
$OG_PASSPHRASE  = 'a-long-private-string';

Then enter that passphrase in the box at the top of this page. It is kept in this browser only and sent to your own server, never to OpenAI.

The passphrase is not decoration. This page spends real money on your account. Without it, anyone who discovers the URL has a free image generator billed to you. Use something long, and change it if you ever paste this page's URL somewhere public.

The Server check table at the top of the page reports what PHP actually found when the page loaded — which file it read, and whether each value is set. If something is wrong it says so there, in plain words, before you press anything.

Generating
  • Generate on a single card sends that one prompt. Expect fifteen to forty seconds.
  • Generate all missing works through everything without an image yet, two at a time. Fifty-five images is a real spend — check the price on your OpenAI dashboard before starting a full run.
  • Quality low / medium / high trades cost against fidelity. Medium is usually right for something viewed at thumbnail size in a chat window.
  • Images are held in memory only. Closing the tab loses anything not downloaded. This is deliberate — fifty-five full-size images would overflow browser storage.
Cropping and the shape problem

The model returns 1536 × 1024, which is 3:2. Open Graph wants 1200 × 630, which is nearly 2:1. Something has to be cut from the top and bottom — about a fifth of the height.

Every prompt therefore asks for the subject in the central horizontal band with uncluttered space above and below. When a crop still lands badly, use the vertical crop slider on that card to slide the window up or down rather than regenerating.

Editing prompts and wording

Open Prompt & wording on any card. Changes apply to the next generation and are kept in this browser between visits, so a prompt you have improved is not lost on reload. Reset restores the shipped version.

Wording changes redraw immediately — no API call, no cost. Line one should be three to five words; line two, six to eight. Both must be legible at the size WhatsApp actually renders them, which is very small.

Using the results

Download gives a PNG named for the page. Download all gives a zip of everything generated.

Upload each to the site it belongs to, then add to that page's <head>:

<meta property="og:image" content="https://example.com/og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:title" content="...">
<meta property="og:description" content="...">

WhatsApp caches previews hard. After adding the tags, a link already shared may keep showing the old blank preview for days. Facebook's Sharing Debugger will force a re-scrape.

File format and size

The default is JPEG at 82, which puts a 1200 × 630 frame in the region of 50–90 KB. The earlier version wrote PNG, which is lossless and therefore hopeless for a photograph — the same picture ran past a megabyte for no visible gain.

The Compression slider changes the encoder quality and the size readout on each card updates as you drag, so you can find the point where it starts to show. The flat graphic prompts tolerate far more compression than the photographic ones; 70 is usually invisible on a flat vector image and occasionally visible on a beach.

WebP is offered and is roughly half the size of JPEG at the same quality — but think twice before using it for an OG image. Preview rendering is done by whatever bot the messaging app happens to run, and WebP support across those is patchier than it is in browsers. WhatsApp is the case you actually care about, and a preview that silently fails to render defeats the entire exercise. JPEG is universally understood. Use WebP on your pages, not in og:image.

Changing the format changes the file extension in the meta block too, so the tags and the files you upload always agree.

Getting the tags onto 55 pages without losing your mind

Every tag is derived from what is already on this page, so nothing has to be written per site. The order that works:

  1. Decide one home for the images and put them all there. One folder, one absolute URL, e.g. https://sas.vc/og/. OG images may be cross-origin, so pages on teamkilimanjaro.com and cofec.org can point at a file on sas.vc quite happily. Set that URL in the box at the top and every block on this page updates.
  2. Name the files as downloaded — og-tide.png, og-arien-care.png. The Download buttons already use those names, so the URLs in the meta blocks are correct without you recording anything.
  3. Work down the page, not across your sites. Open a card, press Copy, paste, tick Pasted into the page. The card dims and the counter at the top moves. Close the tab and come back next week — the ticks are still there.
  4. Verify in bulk, not one at a time. Load index.php?ogrefresh=1. Every card whose page now has an image loses its red hatched box. That is your progress report, and it reads the live pages rather than trusting this checklist.

For Automad pages, switch Meta output to Plain fields. You get the title, description and image URL as separate values to paste into the page's fields, rather than an HTML block that has nowhere to go.

Copy every block puts all 55 on the clipboard at once, with a comment header naming each page — useful if you would rather work in an editor with the whole lot in front of you than click through cards.

Note what og:title is set to: the tool's name, not the strapline. The strapline is already in the picture, and a preview that says the same thing twice wastes the single line of text anyone actually reads.

The restricted tools

Thirteen entries at the end share one deliberately uninformative image. That is not laziness.

An OG image is fetched by anything that sees the URL — every forward, every link scanner. A well-made preview for the costing tool advertises that the costing tool exists and roughly what it shows, to everyone the link ever reaches. Those pages are locked because their contents are commercially sensitive. One generic lock image gives a tidy preview without the disclosure.

Server check — run when this page loaded, not by the browser

og-config.php OK found at /home/customer/www/sas.vc/private/og-config.php
$OPENAI_API_KEY OK set
$OG_PASSPHRASE OK set
config is silent OK prints nothing, as required
PHP cURL OK available
not tested

Images generated with OpenAI gpt-image-1. Wording composited locally.