Skip to content
Twilight React Playground
ثيم رائدaren

useAsset

hookBeginnerserverbrowserlive demo

Builds URLs for your theme's own asset files and for Salla's asset CDN, optionally asking the CDN to resize an image.

import { useAsset, UseAssetResult } from '@salla.sa/twilight-theme-engine/hooks/useAsset';

In plain words

Images and files need full web addresses. asset('images/logo.png') builds the address of a file your theme serves under /assets/, and cdn('images/banner.jpg', 400) builds an address on Salla's asset CDN that asks for the image at 400 pixels wide.

These functions only build text. Nothing is downloaded until a browser uses the URL, for example in an <img>.

Signature

function useAsset(): UseAssetResult

interface UseAssetResult {
  asset: (path: string) => string;
  cdn: (url: string | null | undefined, width?: number, height?: number) => string;
  isPlaceholder: (url: string | null | undefined) => boolean;
}

Try it live

useAsset() only builds URL strings: nothing is fetched. The last two rows use the real store logo, an absolute URL.Try this: set width to 0 and height to 0: the resize segment disappears. Notice the logo URL never changes, whatever the size.
Storefront canvas · en · LTR
asset(path)
/assets/images/banner.jpg
cdn(path)
https://cdn.assets.salla.network/images/banner.jpg
cdn(path, width, height)
https://cdn.assets.salla.network/cdn-cgi/image/fit=scale-down,width=400,onerror=redirect,format=auto/images/banner.jpg
cdn(store logo, width)
https://cdn.salla.network/salla.com/logo-wide-1.svg
isPlaceholder(store logo)
false
Controls
0 means "not set".
0 means "not set".
What a theme writes
import { useAsset } from '@salla.sa/twilight-theme-engine/hooks/useAsset';

export function Banner() {
  const { cdn } = useAsset();
  return <img src={cdn('images/banner.jpg', 400)} alt="" width={240} height={240} />;
}

Example

app/components/HeroBanner.tsx
import { useAsset } from '@salla.sa/twilight-theme-engine/hooks/useAsset';

export function HeroBanner() {
  const { asset, cdn } = useAsset();
  return (
    <picture>
      <source media="(max-width: 640px)" srcSet={cdn('images/hero.jpg', 640)} />
      <img src={asset('images/hero.jpg')} alt="" width={1200} height={400} />
    </picture>
  );
}

How it behaves

  • It holds no state: it returns the pure functions asset, cdn and isPlaceholder from packages/theme-engine/src/utils/asset.ts, which @salla.sa/twilight-theme-engine/utils also exports for use outside components (loaders, head).

  • asset(path) returns the root-relative /assets/<path>, with leading slashes removed from path.

  • cdn(path) returns https://cdn.assets.salla.network/<path>. With a width or height it returns https://cdn.assets.salla.network/cdn-cgi/image/fit=scale-down,width=W,height=H,onerror=redirect,format=auto/<path>, leaving out whichever size is not given.

  • Both append ?v=<VITE_TWILIGHT_VERSION> when that build-time variable is set.

Gotchas

  • cdn() returns any URL starting with https:// unchanged and ignores the sizes. Product and store images from the Salla API are absolute URLs, so cdn(product.image.url, 400) does not resize them.

  • Only https:// counts as absolute. An http://… or //host/… URL is appended to the CDN origin and becomes a broken address.

  • cdn(null), cdn(undefined) and cdn('') return the bare CDN origin, which is not an image. Check for a missing URL first.

  • isPlaceholder() always returns false: the placeholder URL it compares against is hard-coded to null.

  • The JSDoc in the source names https://cdn.salla.network; the real origin is https://cdn.assets.salla.network.

Related

Source and docs