Component icons and project banners

TL;DR

  • A component carries an icon; a project carries an avatar and a banner. A backend has no presentation of its own, and a solution entry inherits the project's.
  • Upload is not storage: an avatar is re-encoded to 512 × 512 WebP and a banner to 1920 × 480 WebP, center-cropped to that aspect first. Author at the exact output size or the crop decides your composition for you.
  • Accepted inputs are JPEG, PNG and WebP, decided by reading the bytes. Avatars cap at 5 MiB, banners at 10 MiB, and neither may exceed 6000 px on a side.
  • ppl component update --icon ./icon.png and ppl project update <id> --avatar @./icon.png --banner @./cover.png upload and bind in one step.
  • Assets are served publicly. Nothing confidential belongs in one.

Where presentation lives

EntityIcon / avatarBannerNotes
ComponentyesnoSet from icon.png at creation, or with --icon later.
ProjectyesyesThe git repository for a backend; the card everyone browses.
BackendinheritedinheritedA working tree carries no presentation of its own.
SolutioninheritedinheritedCopied from the project when published, and kept in step afterwards.
ApplicationnonoApplications are addressed by name, not by card.

What the platform does to an upload

Every asset passes through one path: decode, dimension check, center crop to the target aspect, scale, re-encode as lossy WebP at quality 80.

KindStored asAspectAcceptsCaps
Avatar / icon512 × 512 WebP1:1JPEG, PNG, WebP5 MiB, 6000 px per side
Banner1920 × 480 WebP4:1JPEG, PNG, WebP10 MiB, 6000 px per side

Transparency survives the re-encode, so a rounded-corner icon on a transparent background stays that way. The format is derived from the bytes rather than from the file name or the declared content type — an SVG must be rasterized before it can be uploaded.

Designing for the crop

The crop is centered and happens before the scale, which makes aspect ratio the load-bearing decision:

  • A 16:9 frame cropped to 4:1 keeps 44% of its height. Screenshots make poor banners.
  • A portrait photograph cropped to 1:1 loses its sides.
  • An image smaller than the output is upscaled, and quality-80 WebP does not hide that.

An icon is read at roughly 48 px in a catalog row, so it wants one silhouette, two or three flat colors and thick strokes — no text, no hairlines. Banner content belongs inside the middle 60%, because surfaces overlay the display name on it. Flat vector art survives the re-encode cleanly; photographs and long smooth gradients band.

Setting them

ppl component update --icon ./icon.pngppl project update <project_id> --avatar @./icon.png --banner @./cover.png

The @ prefix uploads a local file. A bare value binds an asset reference that already exists, which is how several projects share one image.

A component picks up a sibling icon.png automatically at creation, and on a later update only while it still carries the default placeholder. After a real icon is set, changing it means naming --icon explicitly — a re-run of the directory sync will not overwrite it.

Related

Was this page helpful?