Skip to content

Image

A static or synced image display. Can show SF Symbols, remote URLs, or synced image URLs.

Type

"image"

Relevant Fields

Inherits all Control Definition. Key fields:

Field Type Default Description
systemName string — SF Symbol name (fallback/placeholder)
url string — Static remote image URL
style string — "rounded" for rounded corners, "circle" for circular clipping
imageCornerRadius number — Custom corner radius
aspectRatio string — "fit" (scale to fit) or "fill" (scale to fill, may crop)
hideBackground bool false Remove glass background
iconMap object — Incoming value → SF Symbol name — see Value maps
valueMap object — Incoming value → image URL
colorMap object — Incoming value → hex tint for the mapped symbol

Value maps

An image doesn't have to be fed a URL: point it at a code — a WMO weather code, a device state, an alarm level — and let the layout say what that code looks like.

"iconMap": { "0": "sun.max.fill", "3": "cloud.fill", "61": "cloud.rain.fill", "default": "questionmark.circle" },
"colorMap": { "0": "#FFD60A", "61": "#0A84FF" }
  • Keys match the stringified value, so 0, "0", true, and "rain" all work from the same map. true/false also match yes/no/on/off/1/0, and a number matches whether it arrives as 61 or 61.00. Key lookup falls back to a case-insensitive match.
  • "default" is the catch-all for any value with no entry; with no "default" either, the image falls back to its own systemName rather than rendering blank.
  • Precedence: a valueMap URL wins, then an iconMap symbol, then the synced value as a URL, then the static url, then systemName.
  • Only absolute URLs load (a synced bare code is never mistaken for an address).
  • colorMap tints the mapped symbol; a photo is unaffected.

Label takes the same three fields, where valueMap supplies display text.

Examples

SF Symbol placeholder (e.g., for camera feed)

{
  "type": "image",
  "id": "cam-front",
  "position": [0, 0],
  "span": [1, 2],
  "systemName": "video.fill"
}

Synced album artwork

{
  "type": "image",
  "id": "album-art",
  "position": [0, 0],
  "span": [3, 2],
  "systemName": "music.note.list",
  "style": "rounded",
  "imageCornerRadius": 8,
  "hideBackground": true,
  "sync": [{ "method": "meshsocket", "type": "listen", "event": "broadcast", "filter": { "msg_type": "player_state" }, "valuePath": "artwork_url" }]
}

Live weather icon (WMO code → SF Symbol, no server)

{
  "type": "image",
  "id": "wx-icon",
  "position": [0, 0],
  "span": [2, 2],
  "systemName": "cloud",
  "hideBackground": true,
  "iconMap": { "0": "sun.max.fill", "1": "sun.max.fill", "2": "cloud.sun.fill", "3": "cloud.fill", "45": "cloud.fog.fill", "51": "cloud.drizzle.fill", "61": "cloud.rain.fill", "71": "cloud.snow.fill", "80": "cloud.heavyrain.fill", "95": "cloud.bolt.rain.fill", "default": "questionmark.circle" },
  "colorMap": { "0": "#FFD60A", "1": "#FFD60A", "2": "#FFD60A", "61": "#0A84FF", "80": "#0A84FF", "95": "#FF9F0A" },
  "sync": [{ "method": "http", "url": "https://api.open-meteo.com/v1/forecast?latitude=42.36&longitude=-71.06&current=weather_code", "interval": 900, "valuePath": "current.weather_code" }]
}

Hero symbol tile

{
  "type": "image",
  "id": "wx-hero",
  "position": [0, 0],
  "span": [3, 2],
  "systemName": "sun.max.fill",
  "tint": "#FFD60A",
  "hideBackground": true
}

The symbol fills the cell, so the span alone controls how big it reads.

Device state → symbol

{
  "type": "image",
  "id": "printer-state",
  "position": [0, 2],
  "span": [2, 2],
  "systemName": "printer",
  "iconMap": { "idle": "printer", "printing": "printer.fill", "error": "exclamationmark.triangle.fill", "default": "questionmark.circle" },
  "colorMap": { "printing": "#30D158", "error": "#FF453A" },
  "sync": [{ "method": "meshsocket", "type": "listen", "event": "broadcast", "filter": { "msg_type": "printer" }, "valuePath": "state" }]
}

Behavior

  • When synced, receives a URL string and loads the image from that URL
  • systemName renders as SF Symbol when no URL is available
  • A symbol scales to its cell, exactly as a photo does: give the control a [3, 2] span and it renders as a hero tile, not a small glyph in a large box. It never shrinks below a legible ~28pt, which is also the size it settles at in a flow grid (where the cell has no fixed height) — set controlHeight there to make it larger. See Grid Dimensions
  • iconMap/valueMap/colorMap turn a synced code into a symbol, an image URL, and a tint — see Value maps
  • Supports long-press groups for detail views