Media and assets

Where a storefront's images and files come from — the Storage delivery path on your own domain, transforming images at request time, the Nuxt Image provider, and the theme's own image routes.

A storefront's binary assets — product imagery, spec sheets, brand logos, marketing video, 3D models — live in Storage. You upload once and serve whatever each page needs, resized and reformatted at request time.

Two surfaces

Storage has a management side and a delivery side, and keeping them apart matters:

SurfaceWhereWhat it's for
The management APIhttps://api.revenexx.com/v1/storageUpload, list, move, delete, mint signed URLs. Authenticated, tenant-scoped.
The delivery pathhttps://shop.example.com/cdn/{folder}/{file}The public read path your storefront links to. Public assets need no auth; private ones need a signed URL.

A storefront overwhelmingly uses the second. Uploading is a back-office job, done through Cockpit or from an integration — not something a theme does at request time.

The delivery path

Assets are served from your own domain under a /cdn/ path — one origin in your markup and one in your CSP. What follows /cdn/ is the path inside your tenant's storage.

text
https://shop.example.com/cdn/<folder>/sunset.jpg

Delivery runs on revenexx's own content delivery edge, cached close to your customers. The platform and its data are hosted in the EU; the edge delivers cached content globally.

Transform at request time

Add parameters to the URL and the edge returns a derivative, then caches it:

text
https://shop.example.com/cdn/photos/sunset.jpg?w=800&fm=webp
text
https://shop.example.com/cdn/photos/sunset.jpg?w=300&h=300&fit=crop&gravity=ce

The first request for a combination is generated at the edge; every later request for that URL is served from cache. You never regenerate the same variant twice, and you never store more than the original.

The parameters you'll use most: w and h for size, fit for how the image fills the box, fm for the output format, q for quality, dpr for high-density screens, and gravity for where a crop anchors. The full list, including smart cropping and focus points, is in Serve and transform images.

The Nuxt Image provider

Because a theme is a Nuxt app, the practical way to use all of the above is the Storage provider for @nuxt/image. <NuxtImg> and <NuxtPicture> then emit transform URLs for you, targeting your own domain's /cdn/ path:

Vue
<template>
  <NuxtImg
    :src="product.imagePath"
    :width="400"
    :height="400"
    fit="crop"
    format="webp"
    sizes="sm:100vw md:50vw lg:400px"
    loading="lazy"
  />
</template>

That gets you responsive srcsets, modern formats, and lazy loading without hand-writing a single query string. Use it rather than composing URLs yourself — hand-built URLs are how a page ends up shipping 2000-pixel images to phones.

The theme's own image routes

The base layer adds two BFF routes for product imagery, so blocks don't need to know how a product's media is addressed:

RouteFor
GET /api/images/list/{name}The image used in list and card contexts
GET /api/images/detail/{filename}The image used on a product detail page

The useProductImage composable is what blocks actually call. Two reasons to go through it rather than reaching for a URL directly: it resolves the right variant for the context, and it handles the placeholder case.

Placeholders are the normal case right now

The live catalog index does not yet carry images, so a product read against live data resolves to a placeholder rather than to real imagery. See Catalog, cart and checkout.

Design for it. A card whose layout collapses without an image, or which shows a broken-image icon, is a bug you will hit on the first live tenant. A card that renders a placeholder of the right aspect ratio is correct today and stays correct when the index fills in.

3D models

Storage also serves 3D assets, and the reference theme has a model block for them. A model is delivered from the same /cdn/ path, and a poster raster can be requested for it so a gallery has something to show before the viewer loads. See 3D assets.

Multi-tenant note

Each tenant is served on its own domain, so asset URLs are naturally per tenant. What isn't automatic is anything you cache — a resolved logo URL, a mapping from product to image path. Put the tenant in the key. See Multi-tenant themes.

Per-tenant logos and brand assets belong in the branding payload rather than bundled into the theme — see Design tokens.

Next steps

Was this page helpful?