Playbook · Shopify custom fonts / @font-face not loading

Shopify custom fonts / @font-face not loading — CORS, theme assets, Shopify Fonts, CDN.

Written for a Shopify DTC owner whose brand or custom fonts fail to apply — @font-face rules fire but the face never paints, console shows CORS / failed font, Network shows .woff / .woff2 / .ttf blocked or 404 — theme Assets paths, Shopify Fonts picker, Cross-Origin headers, or a CDN / Cloudflare rule. DIY-first: prove the font URL in Network, fix CORS / asset path / Shopify Fonts / proxy, hard-refresh. Distinct from CDN product images not loading, Liquid error on product page, theme editor publish failing, and www redirect loop. No earnings claims, no invented case studies.

Nico at Latch AI Ops · Sep 8, 2026 · ~12 minute read

Buy the 72-hour install — $997CDN imagesLiquid errorMerchant FAQ

01

Custom fonts / @font-face not loading — not CDN images, liquid-error, theme-editor, www-redirect.

Several products can look like “my theme fonts broke.” They do not share a settings panel. This page is only when custom / brand fonts or @font-face requests fail while layout, images, and add-to-cart still render — fallback system fonts show instead of the brand face. Broken product / collection images from Shopify CDN are cdn-shopify-images-not-loading. A red Liquid / theme error string on the PDP is liquid-error-on-product-page. Theme editor Save / Publish that refuses is theme-editor-publish-failing. www / non-www redirect loop is www-redirect-loop-shopify. This page is only: custom fonts / @font-face not loading.

Six ordinary reasons custom fonts fail: CORS / Access-Control-Allow-Origin or Cross-Origin-Resource-Policy blocking the font file, a wrong theme Assets path or broken @font-face src / font-display, Shopify Fonts not selected while CSS still names a missing face, a third-party font CDN or Cloudflare Rocket Loader / Hotlink mangling font fetches, the .woff2 never uploaded to Assets, or you are debugging CDN product images, Liquid error text, theme editor publish, or www redirects instead. Walk them in that order. You already pay for Online Store. You do not need another seat to clear a font CORS row.

02

Prove the font URL in Network and open it alone.

Open the live storefront in a private window. DevTools → Network → Font (or All). Reload. Find the failing request — usually a .woff2 / .woff / .ttf under theme Assets, cdn.shopify.com, or a third-party font host. Status 404 means the file path is wrong or the asset was never uploaded. Status (failed) / CORS / opaque often means Cross-Origin headers or CORP. Status 200 with the wrong Content-Type can still leave the face unapplied.

Paste the URL into a new tab alone. Open Console for Access-Control-Allow-Origin or font-face errors. Compare Themes → … → Edit code → Assets: is the file there? Does Typography / Shopify Fonts name the same family your CSS expects? Honest proof: if only fonts fail while images and Liquid render fine, stay on this page. If product images 404 from Shopify CDN, leave for cdn-shopify-images-not-loading. If the PDP prints Liquid error / theme error text, leave for liquid-error-on-product-page. Do not mix those proofs.

03

CORS / Access-Control-Allow-Origin blocking .woff2 or Cross-Origin-Resource-Policy.

Browsers treat fonts as CORS-sensitive. A @font-face that points at another origin without Access-Control-Allow-Origin (or with a strict Cross-Origin-Resource-Policy) will fail even when the URL returns 200 alone. Classic pattern: font hosted on a marketing CDN, S3 bucket, or old agency domain while the shop runs on myshopify.com or a custom domain.

Fix: move the face into theme Assets and reference it with Shopify’s asset helpers so it serves from the same CDN family as the theme, or configure the external host to send ACAO for your shop origins. Prefer same-origin / Shopify-hosted files over a third-party bucket you do not control. Hard-refresh and recheck Network → Font. Pure www / non-www ERR_TOO_MANY_REDIRECTS without a font CORS row is www-redirect-loop-shopify.

04

Wrong theme Assets path, @font-face src, or missing asset_url / font_url.

Hard-coded /assets/Brand.woff2 paths, typos in the filename, @font-face in a CSS file that never loads on Current, or missing asset_url / font_url filters produce 404s. Draft themes can look correct while Current still serves the old CSS without the face.

Fix: Online Store → Themes → … → Edit code on Current. Upload the .woff2 (and fallback .woff if needed) under Assets. In CSS / Liquid use Shopify helpers, for example {{ 'Brand.woff2' | asset_url }} inside @font-face src, with a matching font-family and font-display. Save on Current / Published. Hard-refresh. If Save / Publish in the theme editor fails entirely, leave for theme-editor-publish-failing. If the page prints a Liquid error string instead of a missing face, that is liquid-error-on-product-page.

05

Shopify Fonts picker vs self-hosted custom faces.

Online Store 2.0 themes expose Typography / font pickers backed by Shopify Fonts. If the theme setting still names a system or Shopify Font while your custom CSS expects a self-hosted family — or the reverse — headings fall back silently. Custom faces that are not in Shopify Fonts must be self-hosted as Assets with a correct @font-face; picking a similar Shopify Font is often the lower-friction path when licensing allows.

Fix: Themes → Customize → Theme settings → Typography on Current. Align heading / body font picks with the families you intend. If you need a licensed brand face Shopify Fonts does not offer, keep the self-hosted @font-face path and remove conflicting theme font-family overrides. Publish Current. App embeds that inject CSS and never appear at all are closer to app-embed-not-loading.

06

Third-party font CDN, Cloudflare Rocket Loader, or Hotlink mangling fonts.

Google Fonts / Adobe Fonts / Typekit and other font CDNs need a working stylesheet link and CORS-friendly font files. Ad blockers, CSP, or a removed kit ID break those loads. Cloudflare Rocket Loader, Hotlink Protection, or aggressive cache rules on the shop hostname can also break font fetches — especially when CSS expects fonts from your domain while proxy rules strip or block them.

Fix: confirm the third-party kit / CSS link still loads; or move to theme Assets + @font-face. Cloudflare → DNS grey-cloud the Shopify primary host per Shopify guidance, or exclude font paths from Hotlink / Rocket Loader. Purge cache. Retest Network → Font. Product image 404s without font failures are cdn-shopify-images-not-loading. Custom domain / SSL still pending is custom-domain-ssl-not-connecting.

07

You tested CDN images, liquid-error, theme-editor, or www-redirect instead.

CDN product images broken or 404 is cdn-shopify-images-not-loading. Liquid error / theme error text on product or collection is liquid-error-on-product-page. Theme editor Save / Publish failing is theme-editor-publish-failing. www / non-www redirect loop is www-redirect-loop-shopify.

The only honest test for this page: custom / brand fonts or @font-face fail to load (CORS, 404, or unapplied face) while the rest of the page loads. Capture the font URL, repair CORS / theme Assets / Shopify Fonts / CDN proxy, publish Current, retest. Anything else is a different product.

08

When to stay DIY vs pay $997.

Stay DIY if you can spend one afternoon on the list above: prove the font URL, fix CORS / CORP, upload Assets with correct asset_url / @font-face, align Shopify Fonts vs self-hosted, and stop confusing CDN images / liquid-error / theme-editor / www-redirect with a missing face. That is the whole playbook. No agency required. Short answers also live on the merchant FAQ. Related pages: cdn-shopify-images-not-loading, liquid-error-on-product-page, theme-editor-publish-failing, www-redirect-loop-shopify.

Pay for help when the work is not the missing @font-face row — it is connecting the stack you already have so lead capture is not dying in DMs, storefront and checkout-ready exceptions land in a channel you already check, and the live store is one workflow instead of a spreadsheet plus a Slack bot you forgot. That is the Latch AI Ops install.

What $997 USD one-time buys: lead capture on the live store, ops alerts in a channel you already check, and a checkout-ready workflow. 72 hours after collaborator access, not after payment. One live Shopify store. Access plus a delivery thread. Store URL collected at checkout. Not a SaaS seat, not a theme rebuild retainer, not a conversion guarantee, not a brand or theme job.

Other shops’ public ranges, not testimonials: a checkout / ops install typically runs $500–$2,500. A full ops consulting block typically runs $2,000–$5,000. $997 is the cheap end of that work, sold as a 72-hour install of three systems — not as an earnings number or conversion-lift claim.

What it does not buy: more orders, recovered revenue, a forever font / CDN guarantee, or a case study. Latch AI Ops has not published customer proof because there are no customers yet. You are buying the install.

Checkout is on Whop. Operator is Nico. United States offer. You can revoke collaborator access after handoff. We do not take owner passwords.