Guides

Working with images and files from the asset library

How to read image and file URLs from the Merchant API, request the size and format a page needs, read product files, and upload with texts per language.

Images and files are moving to the asset library. It's one place to upload and organise them and give them texts in every language. The library can also resize any image to whatever size a page asks for.

You can use the asset library today. Everything you upload gets a CDN address, and you can link it to products in Studio. Until the account is migrated, the Merchant API lists such an image by file name only, without a url, and no address can be built from the file name, since the file exists only in the library.

The migration copies the account's existing images into the library. They stay available at their old address and get a new address under cdn.litium.media, which the Merchant API returns as url. Images added after the migration exist only in the library and have a url from the start.

This guide covers the changes you need to make:

  1. Reading image URLs from the Merchant API, for products and CMS widgets
  2. Asking for the size and format each page needs
  3. Reading product files
  4. Uploading with texts per language

We set the migration date for each account together with you, so your changes can go live by then.

Before you start

Check whether the account is migrated. The url fields tell you.

Migrated accountNot migrated
url on images and filesA CDN URL. Query parameters give another size or format.null
channel.assetHosthttps://cdn.litium.media/<account>null
Image URL to renderurl as returnedThe legacy URL built from the file name

Note: Never build a library URL from fileName. The folder is part of the URL, and fileName doesn't include it.

1. Read the image URLs

Select url next to fileName wherever you read images. productImages come in the order they have on the product.

product(alias: $alias) {
  productImages { fileName url }
}

The product's assets list the same images too (linkType: "productimage"), in link order, oldest first, not gallery order. An asset linked as both image and file appears twice. assets exists on the product only, not on variants or related products. On a not-migrated account a library image linked to the product appears in productImages with its fileName and url: null, and assets is [].

A CMS widget returns two things for an image. Its images[] carries fileName and url. For a library image largestSize is null and sizes is empty.

Its configuration carries the library path: image.path on Image and Banner widgets, and a <field>Path next to every image field on JSON widgets. JSON widgets have an empty images[].

To build a URL from a path, put the channel's assetHost in front of it. It is the account's CDN address, or null when the account is not migrated.

query {
  channel(channelId: "1|se") {
    assetHost   # https://cdn.litium.media/acme
  }
}

https://cdn.litium.media/acme + / + content/hero.png → https://cdn.litium.media/acme/content/hero.png

WhereLibrary URLLegacy URL
Product images, also in cart, checkout and ordersurlhttps://<account>.commerce.services/product/raw/<fileName>
CMS Image and Banner widgetsimages[].url of the entry with the same fileName, or assetHost + / + image.path…/pagewidget/raw/<fileName>
CMS JSON widgets (cards)assetHost + / + <field>Path…/pagewidget/raw/<fileName>
  • One read: assetHost is the same for every channel on an account.
  • No url: category, brand, variant and related-product primaryImage are file names only and stay on the legacy host.

2. Request the size and format you render

Add width and format=auto to a library URL.

<img src="…/drill.jpg?width=800&format=auto"
     srcset="…/drill.jpg?width=320&format=auto 320w,
             …/drill.jpg?width=640&format=auto 640w,
             …/drill.jpg?width=1200&format=auto 1200w"
     sizes="(min-width: 768px) 400px, 100vw" alt="Cordless drill">
ParameterResult
width=<px>The image at that width, aspect kept. No upscaling unless you add enable=upscale.
height=<px>The image at that height, aspect kept. With width as well, the image is stretched to both unless you set fit.
fit=crop, fit=boundsWith width and height: crop fills the box and crops the middle; bounds fits inside the box, aspect kept.
canvas=1:1&bg-color=<hex>Pads a non-square image to a square with that background colour.
quality=<1–100>Compression level of the rendered image.
format=autoThe CDN picks the format from the browser's Accept header: AVIF, WebP or JPEG XL, otherwise the original.
No formatThe stored format (JPEG, PNG, …), or WebP where the Accept header allows it. AVIF and JPEG XL come only with format=auto. A client that accepts nothing modern, such as a crawler, gets the stored format.
  • Encoding: when you build a URL from a path, encode each segment with encodeURIComponent plus !'()*: group 2.jpg → group%202.jpg.
  • Case: the path is case-sensitive. The platform stores it lowercased.

3. Read product files

A product's documents are its assets with linkType: "productfile".

product(alias: $alias) {
  assets {
    name url linkType mediaType sizeBytes
    description { language value }
    altText { language value }
  }
}
FieldWhat it holds
description, altTextA list with one entry per language
mediaTypepdf, doc, image or other. Word and Excel are both doc; the extension in name is exact.
sizeBytesThe stored size. The bytes served differ for images, which the CDN re-encodes, also when the image is linked as a file.
urlThe file inline, without content-disposition; the browser decides how to show it.
url?download=1The file as an attachment, under its own name.

4. Upload with texts per language

Every upload route lands in the asset library and gets a url: Merchant Center, the media API (media/*) and the legacy management API (Product/{id}/Image).

Put every language, the default one too, under localizations.<language>. Text at the top level has no language and comes back as language: null.

Good to know

  • URLs change: a file's URL changes when the file is renamed or moved.
  • Caching: browsers cache CDN images for one hour (max-age=3600).