Skip to content

Brand for generated images

When the media module renders an image from HTML (blog autopilot’s html_render image strategy, for example), it uses your brand profile’s colours, fonts and logo. The model never picks a hex code or a font family. It only uses the brand tokens you define here.

  1. Open the admin and go to Settings → Brand.

  2. In Colors and fonts, enter a six-digit hex value (#RRGGBB) for each colour role you use, or pick one with the colour swatch. Leave a role empty to skip it.

  3. Choose a Google Font for each font role you use.

  4. Select Save brand. The next generated image uses the new values. Images you already generated keep their old colours until you regenerate them.

Each colour becomes a CSS custom property that the generated HTML must use.

Key Token Role
primary --brand-primary Main brand colour for headlines and key shapes.
accent --brand-accent Highlight. Use it at most once per image.
accent_text --brand-accent-text Accent surface that carries text.
canvas --brand-canvas Background.
ink --brand-ink Body text.
muted --brand-muted Secondary text and rules.
primary_dark --brand-primary-dark Primary text on dark backgrounds.

The API rejects unknown keys and values that aren’t #RRGGBB. The admin form blocks the save and marks the field before it sends anything.

Key Token Used for
display --brand-font-display Headlines
body --brand-font-body Running text
mono --brand-font-mono Code, figures and labels
bangla --brand-font-bangla Bangla script

The renderer loads fonts from Google Fonts at weights 400, 600 and 700 by default. A family name can contain only letters, digits and spaces.

The logo comes from the brand profile’s logo_upload field. You set it in the deep-ops console (api.your-domain.com/admin/ → Brand → Brand profiles). The renderer embeds it in the image and places it with the .brand-logo class.

You don’t need to configure anything for this. Each generated design goes through these checks:

  1. The model gets the token names and roles, never the hex values.
  2. The renderer adds the :root tokens, the font stylesheet and the logo to every document.
  3. A validator checks the design for literal colours, fonts outside the brand, undefined --brand-* tokens, and an accent used more than once.
  4. If it finds a problem, the model gets one retry with the problems listed.
  5. If the retry still breaks a rule, the renderer replaces each literal colour with the nearest brand token and logs HtmlImageService:brand_fallback.

A client profile can carry a brand block with palette and typography. seed_client writes it through the same validation as the admin form and stops with Invalid brand block if a value is wrong:

{
"brand": {
"palette": { "primary": "#310DFA", "canvas": "#FBFAF8" },
"typography": { "display": "Plus Jakarta Sans", "body": "Plus Jakarta Sans" }
}
}
Terminal window
docker compose exec web python manage.py seed_client --profile your-profile

HTML rendering needs headless Chromium. The standard API image installs it whenever the media module is included. If you build a client image without the media module, HTML images aren’t available and the media readiness check reports the HTML route as not ready.