asset, cdn, isPlaceholder
Build URLs for your theme's own files and for Salla's asset CDN, as plain functions you can call outside components.
import { asset, cdn, isPlaceholder } from '@salla.sa/twilight-theme-engine/utils';In plain words
useAsset() hands these three functions to components. Imported directly, they also work where a hook cannot be called: a route's head() function, a loader, or a plain helper file.
asset('images/logo.png') returns /assets/images/logo.png, a file your theme serves. cdn('images/og.jpg', 1200, 630) returns an address on https://cdn.assets.salla.network that asks for the image scaled to fit 1200 by 630 pixels.
Signature
function asset(path: string): string function cdn(url: string | null | undefined, width?: number, height?: number): string function isPlaceholder(url: string | null | undefined): boolean
Try it live
- asset(value)
"/assets/images/og-cover.jpg"- cdn(value)
"https://cdn.assets.salla.network/images/og-cover.jpg"- cdn(value, width)
"https://cdn.assets.salla.network/cdn-cgi/image/fit=scale-down,width=1200,onerror=redirect,format=auto/images/og-cover.jpg"- getCdnImageUrl(value, { width })
"images/og-cover.jpg"
import { cdn } from '@salla.sa/twilight-theme-engine/utils';
import type { HeadDescriptor } from '@salla.sa/twilight-theme-engine/utils/head';
// A head() runs outside components, so it cannot call useAsset().
export function aboutHead(): HeadDescriptor {
return {
title: 'About us',
openGraph: { images: cdn('images/og-cover.jpg', 1200) },
};
}
Example
import { asset, cdn } from '@salla.sa/twilight-theme-engine/utils';
import type { HeadDescriptor } from '@salla.sa/twilight-theme-engine/utils/head';
export function aboutHead(): HeadDescriptor {
return {
title: 'About us',
// Social networks need an absolute image URL: cdn() gives one.
openGraph: { images: cdn('images/about-og.jpg', 1200, 630) },
links: [{ rel: 'preload', as: 'image', href: asset('images/about-hero.webp') }],
};
}
How it behaves
asset(path)removes leading slashes and returns the root-relative/assets/<path>.cdn(path)returnshttps://cdn.assets.salla.network/<path>. With a width or a height it returnshttps://cdn.assets.salla.network/cdn-cgi/image/fit=scale-down,width=W,height=H,onerror=redirect,format=auto/<path>, leaving out the size that is not given.Both add
?v=<VITE_TWILIGHT_VERSION>when that build-time variable is set, and nothing otherwise.They are the same functions
useAsset()returns; the hook adds no state.
Gotchas
cdn()returns any URL that starts withhttps://unchanged and ignores the sizes. Images from the Salla API (products, categories, the store logo) are such URLs, socdn(product.image.url, 400)downloads the full file. Resize those withgetCdnImageUrl.Only
https://counts as a full URL.http://example.com/a.jpgand//example.com/a.jpgare appended to the CDN origin and become broken addresses.cdn(null),cdn(undefined)andcdn('')return the barehttps://cdn.assets.salla.network, which is not an image. Check for a missing URL first.isPlaceholder()always returnsfalse: the placeholder URL it compares with is hard-coded tonullin src/utils/asset.ts. docs/02-theme-engine-core.md describes it as a working check.Importing
@salla.sa/twilight-theme-engine/utilsoutside Vite (a plain Node script) throwsCannot read properties of undefined (reading 'VITE_TWILIGHT_VERSION'): asset.ts readsimport.meta.envwhen the module loads. Vite, Vitest and the server are fine; the/utils/head,/utils/baseHeadand/utils/cdn-imagesubpaths load anywhere.Two exports are called
cdn: this function, and an HTTP client in@salla.sa/twilight-theme-engine/api/client. Check the import path.
Related
Builds URLs for your theme's own asset files and for Salla's asset CDN, optionally asking the CDN to resize an image.
getCdnImageUrl, getCdnImageSrcSetRewrite a Salla CDN image URL into a resized copy, or into a srcset of several widths, so pictures download faster.
cdnA bare ky client for Salla's public CDN at cdn.salla.network; it sends no store, language or customer headers.