Overview
Spree handles uploads, processing, and delivery for product media. Images are automatically converted to WebP format and preprocessed into multiple sizes for optimal performance.Product Media
A media record carries:- Position for ordering within the gallery
- Media type —
image,video, orexternal_video(defaults toimage) - Alt text for accessibility and SEO
- Focal point coordinates for smart cropping
- Preprocessed named variants for fast delivery
variant_ids— which product variants the media represents. An empty array means it represents the product as a whole.
Product-level Gallery
In Spree 5.5 the product is the default owner of media. Before 5.5, every image was pinned to a specific variant (usually the master), and sharing the same image across variants meant re-uploading the file. From 5.5 onward, an image lives on the product, and any subset of variants can reference it throughvariant_ids — without duplicating the underlying file.
Uploading a product-level image
Creating media from a remote URL
When the image already lives at a public URL, passurl instead of a signed_id — Spree fetches the remote file and stores it as product media, so you skip the direct-upload step entirely.
The fetch runs in the background, so this request returns
202 Accepted with no body — the media appears in the gallery once the download and processing finish. Re-fetch the product’s media to know when it’s ready.Sharing a single image across variants
Pass avariant_ids array on the same media endpoint to link/unlink variants. The server replaces the asset’s link set on every call — empty array clears all links, omitting the field leaves them untouched.
Storefront gallery resolution
The Store API’smedia field on a product returns its gallery — product-level media when present, falling back to legacy variant-pinned images during the transition. On a variant, media returns the assets linked to that variant via variant_ids, falling back to direct variant uploads.
This dual rendering means existing storefronts keep working during the upgrade; new uploads attach to the product, and you opt into a one-shot migration to re-home legacy variant-pinned data when convenient.
Video
A product gallery can hold video as well as images. Spree supports both ways merchants usually have it:
Spree reads the link once, when it is saved, and rejects anything it cannot embed — so a broken URL is caught at the point a merchant enters it rather than in the storefront. What it derives comes back on the media object:
Because the derived fields are on the response, a storefront embeds a video without parsing links itself.
Adding an external video
Uploading a video file
A hosted video is uploaded the same way an image is, withmedia_type telling Spree what it is. Add poster_signed_id to give it a still frame:
Admin SDK
Admin SDK
Spree serves an uploaded video as you uploaded it — it does not transcode. Keep files web-friendly (H.264 MP4 or WebM) so they play everywhere, and prefer an external video for long footage so the provider handles streaming.
Posters
A video has no image of its own, so its sized URLs (small_url, large_url, and the rest) resolve to its poster — the still shown before the video plays. A gallery that only knows how to draw an image still renders the right picture, and can play the video when the shopper asks for it.
Where the poster comes from, in order:
- The one the merchant uploaded —
poster_signed_idon write, editable in the dashboard’s media editor. - The provider’s own still, for a YouTube link.
- Nothing, for a Vimeo link or an uploaded file with no poster — the tile falls back to a placeholder.
Focal Point
focal_point_x and focal_point_y mark the part of an image that must stay in frame when a storefront crops it to a different shape. Both are fractions between 0 and 1, measured from the top left, so { x: 0.5, y: 0.5 } is dead centre — which is also what a storefront should assume when they are null.
Admin SDK
Named Variant Sizes
When an image is uploaded, Spree automatically generates optimized versions in the background:
All variants are cropped to fill the exact dimensions and converted to WebP format.
Store API
Thumbnails (Always Available)
Every product response includes athumbnail_url field — ready to use without any expands. Similarly, each variant includes a thumbnail_url and a media_count counter.
Full Media (On Demand)
On the product detail page, expand media and variants to get the full set of media with all named variant URLs:Media Fields Summary
Media Object Fields
Image Processing
Spree uses libvips for image processing. Images are automatically:- Converted to WebP format for optimal file size
- Preprocessed on upload into all named variant sizes
- Cached for subsequent requests
Storage
Spree supports two storage service types:For production deployments, use cloud storage (S3, GCS, Azure) instead of local disk storage. See Asset Deployment for configuration details.
Best Practices
- Use
thumbnail_urlon listing pages — avoid loading full media via expand - Always provide alt text for accessibility and SEO
- Use named variant sizes (
mini,small,medium,large,xlarge) for optimal performance - Use a CDN in production for faster delivery
- Give every video a poster so a gallery has something to show before playback
Related Documentation
- Products — Product catalog and media
- Products & Categories — Store SDK guide for fetching products,
thumbnail_url, and expanded media - Admin SDK — Admin SDK resource methods, including the nested
products.mediacreate/update calls - Deployment — Assets — Storage and CDN configuration

