Working with images and files from the asset library
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:
- Reading image URLs from the Merchant API, for products and CMS widgets
- Asking for the size and format each page needs
- Reading product files
- 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 account | Not migrated | |
|---|---|---|
url on images and files | A CDN URL. Query parameters give another size or format. | null |
channel.asset | https://cdn.litium.media/<account> | null |
| Image URL to render | url as returned | The legacy URL built from the file name |
Note: Never build a library URL from
file. The folder is part of the URL, andName filedoesn't include it.Name
1. Read the image URLs
Select url next to file wherever you read images. product come in the order they have on the product.
product(alias: $alias) {
productImages { fileName url }
}
The product's assets list the same images too (link), 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 product with its file and url: null, and assets is [].
A CMS widget returns two things for an image. Its images[] carries file and url. For a library image largest 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 asset 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
| Where | Library URL | Legacy URL |
|---|---|---|
| Product images, also in cart, checkout and orders | url | https://<account>.commerce.services/product/raw/<file |
| CMS Image and Banner widgets | images[].url of the entry with the same file, or asset + / + image.path | …/pagewidget/raw/<file |
| CMS JSON widgets (cards) | asset + / + <field>Path | …/pagewidget/raw/<file |
- One read:
assetis the same for every channel on an account.Host - No
url: category, brand, variant and related-productprimaryare file names only and stay on the legacy host.Image
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">
| Parameter | Result |
|---|---|
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=bounds | With 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=auto | The CDN picks the format from the browser's Accept header: AVIF, WebP or JPEG XL, otherwise the original. |
No format | The 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
encodeplusURIComponent !'()*: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 link.
product(alias: $alias) {
assets {
name url linkType mediaType sizeBytes
description { language value }
altText { language value }
}
}
| Field | What it holds |
|---|---|
description, alt | A list with one entry per language |
media | pdf, doc, image or other. Word and Excel are both doc; the extension in name is exact. |
size | The stored size. The bytes served differ for images, which the CDN re-encodes, also when the image is linked as a file. |
url | The file inline, without content-disposition; the browser decides how to show it. |
url?download=1 | The 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).