Skip to main content

Static Assets

Verse supports four types of visual assets for artworks: images, videos, SVGs, and iframes (interactive/generative content). Each type has a different URL structure and rendering strategy.

Quick Start — Displaying an Asset​

The baseUrlTemplate returned by the API is a template, not a ready-to-use URL. Replace {{SIZE}} and {{FORMAT}} before use:

// Turn a baseUrlTemplate into a displayable image URL (works in any framework)
function resolveImageUrl(templateUrl, width = "w640", format = "webp") {
return templateUrl.replace("{{SIZE}}", width).replace("{{FORMAT}}", format);
}

// Example
const imageUrl = resolveImageUrl(cover.baseUrlTemplate);
// "https://verse.works/content/w640/artwork@webp"

Which field to use depends on the asset type:

Asset typeDisplay as image (thumbnail)Display natively
ImageAssetbaseUrlTemplate — replace {{SIZE}} and {{FORMAT}}Same as thumbnail
VideoAssetpreviewImageUrlTemplate — replace {{SIZE}} and {{FORMAT}}baseUrlTemplate — direct video URL, use in <video src>
SVGAssetpreviewImageUrlTemplate — replace {{SIZE}} and {{FORMAT}}baseUrlTemplate — use with size = "source" and no format
IFrameAssetpreviewImageUrlTemplate — replace {{SIZE}} and {{FORMAT}}iframeUrl — load in an <iframe src>
Common pitfall

If you see literal {{SIZE}} or {{FORMAT}} in your browser's network tab, the placeholders were not replaced. Every image baseUrlTemplate and previewImageUrlTemplate must be resolved before use.

Asset Types​

Every artwork has a cover field that resolves to one of four GraphQL types:

TypePurposeKey fields
ImageAssetStatic or animated imagesbaseUrlTemplate, isGif, width, height, aspectRatio
VideoAssetNative video filesbaseUrlTemplate, previewImageUrlTemplate, previewAspectRatio
SVGAssetVector artworkbaseUrlTemplate, previewImageUrlTemplate, previewAspectRatio
IFrameAssetInteractive / generative contentbaseUrlTemplate, iframeUrl, previewImageUrlTemplate, aspectRatio

All types share id, baseUrlTemplate, and mimeType. ImageAsset and VideoAsset also carry caption and fileSize.

URL Construction — The Template System​

The backend returns template URLs with two placeholders:

https://verse.works/content/{{SIZE}}/artwork@{{FORMAT}}
PlaceholderReplaced withExample
{{SIZE}}A width token or named sizew320, w640, w1400, w3840, source
{{FORMAT}}An image formatwebp, jpeg, png, gif, avif

Resolving a Template URL​

Replace both placeholders to get a usable URL:

// Standard image — serve as WebP at 640px wide
const url = baseUrlTemplate.replace("{{SIZE}}", "w640").replace("{{FORMAT}}", "webp");
// → "https://verse.works/content/w640/artwork@webp"

// Source file — strip the format segment entirely
const originalUrl = baseUrlTemplate.replace("{{SIZE}}", "source").replace("@{{FORMAT}}", "");
// → "https://verse.works/content/source/artwork"

When you don't want a specific format (SVGs, original GIFs), remove the @{{FORMAT}} segment entirely.

Available Sizes​

From the GraphQL ImageSizes enum:

THUMBNAIL | MEDIUM | FULLSCREEN
W80 | W160 | W320 | W480 | W640 | W980 | W1400 | W2400 | W3840

Plus special string values "source" (original file) and "sq1200" (1200px square crop).

Available Formats​

From the GraphQL ImageFormats enum:

JPEG | WEBP | PNG | GIF | AVIF

Default format is WebP. Recommended format selection:

AssetContextFormat to use
Regular imageAnywebp (default)
GIF imageAnimated display (artwork page)gif (preserves animation)
GIF imageStatic thumbnailjpeg (faster than GIF-to-WebP conversion)
SVGAnyStrip @{{FORMAT}} — serve as original

Responsive Images​

To serve responsive images (e.g. in an <img srcset>), generate multiple URLs at different widths:

const widths = [320, 640, 980, 1400];
const srcset = widths
.map(w => `${baseUrlTemplate.replace("{{SIZE}}", `w${w}`).replace("{{FORMAT}}", "webp")} ${w}w`)
.join(", ");

Video Rendering​

Videos (VideoAsset) use a direct URL — no template placeholders:

<video autoplay loop muted playsinline preload="auto">
<source src="{cover.baseUrlTemplate}" type="video/mp4" />
</video>
  • baseUrlTemplate points directly to the video file
  • For thumbnails, use previewImageUrlTemplate (this is a template URL — resolve it like any image)

IFrame Rendering​

IFrame assets (IFrameAsset) represent interactive or generative content. They can be displayed in two ways:

Live Mode​

Render the interactive content in an iframe:

<iframe src="{cover.iframeUrl}" loading="lazy"></iframe>
tip

Use loading="lazy" to defer loading until the iframe is near the viewport. Consider using location.replace() instead of setting src to avoid polluting browser back/forward history.

Static Preview​

Display the previewImageUrlTemplate as a regular image (resolve the template as usual). This is useful for thumbnails, grids, and contexts where interactive content is not needed.

GLB (3D Models)​

If the iframeUrl ends in .glb, the content is a 3D model. On verse.works, these are routed through a dedicated viewer. For your own integration, you can use any glTF/GLB viewer library (e.g. <model-viewer>).

Some artworks support a high-resolution variant via query parameters appended to the iframeUrl.

SVG Rendering​

SVGs are always served at original size with no format conversion:

const svgUrl = baseUrlTemplate.replace("{{SIZE}}", "source").replace("@{{FORMAT}}", "");

Image Preview / Fullscreen​

When displaying assets in a fullscreen or preview context, each type renders differently:

  • ImageAsset — Full-resolution image. For GIFs, use the original format to preserve animation.
  • SVGAsset — Source-size image with no format conversion.
  • VideoAsset — Native <video> with aspect ratio preserved.
  • IFrameAsset — <iframe> with aspect ratio preserved.

GraphQL Fragment​

A recommended fragment for fetching all asset fields needed for rendering:

fragment AllArtworkCoverFormats on Artwork {
cover {
... on ImageAsset {
id, isGif, width, height, baseUrlTemplate, aspectRatio, caption, mimeType, fileSize
}
... on VideoAsset {
id, width, height, baseUrlTemplate, caption, previewAspectRatio, previewImageUrlTemplate,
mimeType, fileSize
}
... on SVGAsset {
id, baseUrlTemplate, caption, previewAspectRatio, previewImageUrlTemplate, mimeType, fileSize
}
... on IFrameAsset {
id, baseUrlTemplate, caption, previewImageUrlTemplate, iframeUrl, aspectRatio
}
}
}

Troubleshooting​

Images are broken / return 404:

  • Check your browser's network tab. If the request URL contains literal {{SIZE}} or {{FORMAT}}, the placeholders were not replaced. Apply the substitution from the Quick Start section.

Image loads but is the wrong size:

  • Make sure you're using a valid size token. Valid values: w80, w160, w320, w480, w640, w980, w1400, w2400, w3840, source, thumbnail, medium, fullscreen, sq1200.

Video won't play:

  • VideoAsset.baseUrlTemplate is a direct URL (no placeholders). Use it in a <video> or <source> element. Don't apply {{SIZE}}/{{FORMAT}} substitution to video URLs.

Thumbnail is blank for a video/iframe/SVG:

  • For non-image asset types, use previewImageUrlTemplate (not baseUrlTemplate) to display a still thumbnail. See the Quick Start table.