Shopify Fonts Cause FOIT — Fix Invisible Text With font-display: swap
If text on your Shopify store briefly disappears during page load before reappearing in the correct font, you are experiencing Flash of Invisible Text (FOIT). FOIT happens when the browser waits for a custom font to download before rendering text — which can take 1-3 seconds on slow connections. During that time, all text is invisible. Adding font-display: swap to your font declarations tells the browser to render text immediately with a system font, then swap to the custom font when it loads. This eliminates FOIT and typically improves LCP by 200-400ms.
What FOIT is and why it happens
When a browser encounters a font-face declaration without font-display: swap, it uses 'block' behavior by default: text is rendered invisibly for up to 3 seconds while the font downloads. If the font loads within 3 seconds, text appears in the correct font. If not, the browser falls back to the system font. During the invisible period, Google Lighthouse penalizes this as a render-blocking resource and it can significantly impact LCP if the LCP element is text.
Adding font-display: swap to Shopify font declarations
In your theme's base.css or fonts.css: @font-face { font-family: 'MyFont'; src: url('{{ 'myfont.woff2' | asset_url }}') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }. For Shopify's built-in font system using font_face, add it via the font_face filter: {{ settings.type_header_font | font_face: font_display: 'swap' }}. This tells the browser to immediately render text with a fallback font and swap in the custom font when it arrives.
Using Shopify's font_face filter correctly
Shopify's Liquid font_face filter accepts a font_display parameter: {{ settings.type_header_font | font_face: font_display: 'swap' }}. This generates the complete @font-face declaration with font-display: swap included. If your theme uses the older approach of outputting font CSS manually, add font-display: swap to each @font-face block. Also ensure you are loading fonts with font-display: swap on Google Fonts: append &display=swap to the Google Fonts URL.
Font-display values and when to use each
swap: show fallback font immediately, swap when custom font loads. Best for text-heavy content. optional: show fallback font, only swap if the custom font loads within a very short window (browser discretion). Best for non-critical decorative fonts. fallback: 100ms invisible period, then fallback font, swap within 3 seconds. block: up to 3 seconds invisible (the problematic default). For Shopify themes, swap is the correct choice for all body and heading fonts.
The fix: before and after
// CODE_COMPARISON
Frequently asked questions
- What is the difference between FOIT and FOUT?
FOIT (Flash of Invisible Text) is when text is completely invisible while the font loads — the browser block period. FOUT (Flash of Unstyled Text) is when text renders in a fallback font first, then swaps to the custom font — what you get with font-display: swap. FOUT is always preferable to FOIT because users can read the content during loading. The visual 'flash' of swapping is less disruptive than invisible text.
- Will font-display: swap cause a visible font swap flash?
Yes, there will be a brief moment where text changes from the fallback font to the custom font when the custom font finishes downloading. On fast connections where the font loads quickly (under 100ms), the swap is imperceptible. On slow connections, there will be a visible shift. This is the intended tradeoff — visible text with a brief style change is always better than invisible text. Use a similar fallback font (same x-height and character width) to minimize the visual impact of the swap.
- How do I choose the right fallback font to minimize FOUT?
Choose a fallback font with similar metrics to your custom font — primarily x-height (relative height of lowercase letters) and average character width. For sans-serif custom fonts, fallback to system-ui or -apple-system on Apple devices and Segoe UI on Windows. For serif fonts, fallback to Georgia. Tools like Font Style Matcher (meowni.ca/font-style-matcher/) help you adjust CSS to match metrics exactly, minimizing layout shift during swap.
// SCAN_YOUR_CODE
Does your theme have this bug?
Paste your code. Syphio automatically detects and fixes this error and hundreds of others — in seconds.
Validate my Liquid →