Serve assets from Shopify CDN
Serve all theme assets from the Shopify CDN instead of external domains to eliminate connection overhead for each domain.
Shopify serves theme assets, such as CSS, JavaScript, fonts, and images, through its CDN. Storefront asset URLs use your store's own domain under a /cdn path, for example /cdn/shop/files/hero.jpg. Same-origin assets reuse the browser's existing connection to the store.
Every additional domain a page references requires a fresh connection before its first byte arrives: a DNS lookup, a TCP handshake, and a TLS handshake, which together take up to three network round trips. On a mobile connection with 150 ms of latency, this results in a delay of nearly half a second before the asset starts downloading, and each extra domain repeats it. When the externally hosted file is a render-blocking stylesheet or the hero image, that delay directly increases First Contentful Paint and Largest Contentful Paint (LCP).
You don't need to hard-code the cdn.shopify.com domain in your theme. Use Liquid URL filters, and Shopify renders the appropriate asset host for the request.
Move externally hosted files that are part of your theme into the theme's assets/ directory. Reference them by filename with the asset_url filter instead of hard-coding a CDN domain. Shopify chooses the appropriate asset host and appends a version parameter when it renders the theme.
Anchor to Choose the correct filter for each image sourceChoose the correct filter for each image source
Both filters serve from the Shopify CDN. Which one you use depends on where the image lives, and that choice determines whether you can resize the image at request time.
Images that ship with the theme live in assets/ and are referenced with asset_url. Shopify serves these files as-is, so you author the <img> tag yourself and set alt, width, and height explicitly. Without width and height the browser can't reserve layout space, and the image shifts the page as it loads. Reserve this path for fixed-size assets that don't need resizing, such as a logo or an icon.
Images that a merchant supplies aren't theme files. They come from an image_picker setting or an upload through Files, and they arrive at whatever dimensions the merchant chose. Pass these through image_url and image_tag, which resize the image on the CDN and generate srcset, alt, width, and height for you. To describe how wide the image displays in the layout, pass a sizes option to image_tag.
An oversized image in assets/ can't be resized, so if a static image needs responsive transformations, then move it out of assets/ and upload it through Files instead.
asset_url | image_tag isn't supported. asset_url returns a URL string, but image_tag requires the image metadata and transformations returned by image_url.
Anchor to Automatic asset versioningAutomatic asset versioning
The asset_url filter appends version numbers to URLs. When you update a file, the version number changes, forcing browsers to download the new version.
Without versioning, browsers might cache outdated assets for days.
Anchor to CSS background imagesCSS background images
For images referenced in CSS, use asset_url in a .css.liquid file:
assets/style.css.liquid
The source file must have a .css.liquid extension for Shopify to process the Liquid code inside it. Reference it as style.css, without the .liquid extension. Shopify serves the compiled asset under that name.
Anchor to ExamplesExamples
Anchor to Static theme assetsStatic theme assets
Replace hard-coded external domains with asset_url, using markup appropriate to each asset type:
The stylesheet_tag filter generates the stylesheet link. The module script doesn't block HTML parsing. The static image includes dimensions to reserve layout space before it loads, and descriptive alt text for assistive technology. To host fonts in assets/, refer to Self-host web fonts on Shopify CDN.
If you can't move a third-party asset into assets/, then add a preconnect hint so the browser starts the connection early instead of discovering the domain while it parses the HTML.
Anchor to Responsive Shopify imageResponsive Shopify image
For a merchant-supplied image, the image_url filter applies CDN transformations, and image_tag generates the srcset and intrinsic dimensions. Pass the sizes option to describe how wide the image displays in the layout:
This example omits quality, which accepts an integer from 10 to 90. Omit it unless you've measured a smaller file at a specific value. Shopify selects a quality automatically based on the output format, and the automatic result is often smaller than an explicit high value.
For more image patterns, refer to the following guides:
- Use Liquid filter chains instead of manual URL construction.
- Serve correctly sized images with
srcsetandsizes. - Use
image_urlandimage_taginstead of manual CDN URLs.
Anchor to TestingTesting
- In the Chrome DevTools Network panel, add the Domain column from the table header context menu, then sort by it to list every host the page contacts. Audit every host other than your store domain, including origins that Shopify already preconnects to. Move files that you control into
assets/. Exclude app domains and third-party services that don't allow copying files or require dynamic updates. - Select an asset request and open its Timing tab. Same-origin CDN assets report
0 msfor DNS Lookup, Initial connection, and SSL. Non-zero values there are the overhead you remove by moving the file intoassets/. - Record a Performance panel trace before and after the change, then compare Largest Contentful Paint and check whether the LCP resource's load delay shrinks.
Anchor to ReferencesReferences
asset_urlfilterimage_urlfilterimage_tagfilter- Using the Shopify CDN for better performance
- The Shopify platform: CDN
- Self-host web fonts on Shopify CDN
- Avoid request proxies
- Warm up third-party connections early with
preconnect