Skip to main content

Upload

The API holds the storage credentials; sites hold none. Files are content-addressed, so the same image uploaded twice is one object. Alt text is generated at upload if none is supplied and is editable in the library.

Render

An image field stores a URL, not dimensions: one of ours (a CDN URL) or an external one. The SDK helpers apply to CDN URLs; isCdnImage tells them apart, and an external URL renders as a plain src: Because URLs are derived, moving the CDN host or adding a width is a platform change, not a content migration.

The Media slot

<Media image video path alt class sizes /> is the one way to render a slot. It replaces the hand-written <img> idiom, keeps the identical CDN srcset and focal-point output, and adds the video side:
  • video set: <video autoplay muted loop playsinline preload="metadata">, poster resolved from the video host
  • else: <img>, or a transparent placeholder when empty so the slot stays a picker in the admin
It emits the combined-slot anchors (data-e-path, data-e-media, data-e-video-path), which is what opens the combined library instead of the image-only picker.

Converting an existing slot

1

Swap the markup

Replace the <img> block with <Media image={image} video={imageVideo} path="props.image" … />. The image case renders identically.
2

Add the video prop

A ${imageKey}Video prop next to the image one. Absent on live rows reads as empty. No backfill.
3

Update the Add form, if the slot is in a list

{ key: "image", type: "media", videoKey: "imageVideo" }.
Zero data migration: live rows are never touched, and the video side stays empty until an editor picks a clip.

Video

Video uploads go to the video host through the API’s upload and status routes and are stored as mux:{id}. Transcoding can take minutes; the library tile tracks the phase. Static builds localise posters.

Storage is public by URL

Media objects are reachable at their hashed URLs even on a private site. Signed URLs are a later phase.