Checks font-display, WOFF2, preloads, hosting and size of web fonts
Fetch the page β requests the audited URL (redirects followed). A network failure or non-2xx status produces an ERROR response and nothing else is evaluated.
Collect the CSS β reads every inline <style> block and style attribute, downloads every linked stylesheet (including the rel="preload" as="style" pattern), and follows @import one level deep. Up to 30 stylesheets, 10 at a time, 10-second timeout each.
Parse the font rules β extracts every @font-face rule: family, font-display, the sources of the last src descriptor with their formats, weight, style, unicode-range and metric overrides (size-adjust, ascent-override, descent-override, line-gap-override). Font preload links (<link rel="preload" as="font">) are collected from the HTML.
Keep what the browser downloads β a rule is judged only when its family is referenced by CSS outside @font-face (or its file is preloaded), its first supported source is a downloadable file, and its unicode-range covers at least one character of the page text. Declared but unreferenced families are listed in the check data as unusedFamilies and are not judged.
Measure the font files β asks for the size of each downloaded font file with HEAD (falling back to GET), up to 20 files.
Aggregate β any FAIL rule makes the audit FAIL; otherwise any WARNING rule makes it WARNING; when every rule passes the audit is SUCCESS.
Icon fonts (Font Awesome, Material Icons and Symbols, Dashicons and similar, recognised by family name) are exempt from the font-display, family-count and fallback-metric rules, because hiding icon glyphs until the font arrives is the correct behaviour. They are still checked for WOFF2, hosting and file size.
Every row maps to one checkRule* method and one CheckCode. CheckCode suffixes use status ranges: 200 success, 300β399 warning, 400β499 fail, 500β599 error. Rules 400β402 and 302 run once per font family, 300 once per font host, 303 once per preload link, 306 once per font file and 307β308 once per stylesheet.
| CheckCode | Status | When it fires | Recommendation | Why it matters |
|---|---|---|---|---|
37A-WebFontAuditor-400 | FAIL | A text font family the page uses has @font-face rules with no font-display descriptor. | Add font-display: swap (or optional) to the {n} @font-face rule(s) for "{family}" in {stylesheet}. For a Google Fonts stylesheet: Append &display=swap to the Google Fonts URL {stylesheetUrl} so the {n} @font-face rule(s) for "{family}" show fallback text while the font downloads. | Without font-display the browser hides text for up to three seconds while the font downloads. Visitors on slow connections stare at a blank page and many leave before reading. |
37A-WebFontAuditor-401 | FAIL | A text font family the page uses declares font-display: block or auto. swap, optional and fallback pass. | Change font-display: {value} to swap or optional for "{family}" in {stylesheet}. | This setting tells the browser to hide text until the font has downloaded. On slow connections visitors see blank space where the content should be, and many leave. |
37A-WebFontAuditor-402 | FAIL | A font family the page uses has rules whose downloadable sources are all of a known format and none is WOFF2. | Convert {fontFile} to WOFF2 and list it first in the src of "{family}" in {stylesheet}. | WOFF2 is the smallest font format and every current browser supports it. Older formats are noticeably larger, so each new visitor waits longer before text looks right. |
37A-WebFontAuditor-300 | WARNING | Font files are downloaded from a host other than the page's host. | Download the {families} files from {fontHost} and serve them from {pageHost} so the browser does not open a second connection. | Fonts on another host force the browser to look up, connect to and secure a second server before the download can start. That delay lands on the first visit, when impressions are made. |
37A-WebFontAuditor-301 | WARNING | The page uses more than 2 text font families. | Reduce the {n} families ({families}) to 2 or fewer, for example one for headings and one for body text. | Every extra family adds downloads that compete with content and images. Pages with many typefaces load slower, most noticeably on mobile connections. |
37A-WebFontAuditor-302 | WARNING | A text font family loads 4 or more distinct static files for its weights and styles within one unicode-range, and none of its rules is a variable font. | Replace the {n} static "{family}" files ({variants}) with one variable WOFF2 file. | Each weight or style in its own file is another request and more bytes. One variable font file covers all of them and usually weighs less in total. |
37A-WebFontAuditor-303 | WARNING | A <link rel="preload" as="font"> has no crossorigin attribute. | Add crossorigin to <link rel="preload" href="{href}" as="font">. | Fonts are always requested in anonymous mode, so a preload without crossorigin does not match and the browser downloads the file twice. That wastes bandwidth and delays everything queued behind it. |
37A-WebFontAuditor-304 | WARNING | The page preloads more than 1 font. | Keep one of the {n} font preloads ({preloads}), the headline font, and remove the rest. | Preloaded files jump the queue ahead of stylesheets and images. Preloading several fonts slows the content visitors came for instead of speeding it up. |
37A-WebFontAuditor-305 | WARNING | A text font family swaps in (its font-display is not optional) and no @font-face on the page sets size-adjust, ascent-override, descent-override or line-gap-override. | Declare a fallback @font-face for {families} (src: local('Arial') with size-adjust, ascent-override and descent-override) and list it after the web font in font-family. | When the web font replaces the fallback, lines change length and the page jumps. Readers lose their place and the layout shift counts against Core Web Vitals. |
37A-WebFontAuditor-306 | WARNING | A measured font file is larger than the 100 KB budget. | Reduce {fontFile} ({size} KB): subset it to the characters the site uses, for example Latin plus punctuation, which typically cuts 60β80%, and drop variable axes the design does not use. | A font file this large usually carries alphabets and symbols the site never shows. Visitors pay for those bytes on the first visit, which is slowest on mobile data. |
37A-WebFontAuditor-307 | WARNING | Fetching a stylesheet returned a non-2xx HTTP status, so the fonts it declares could not be audited. | Fix the reference to {stylesheet} (HTTP {statusCode}) or remove it from the page, then re-run the audit. | A stylesheet that answers with an error is also failing for visitors, so the page may render with the wrong fonts or unstyled. |
37A-WebFontAuditor-308 | WARNING | A stylesheet could not be fetched at all (timeout, DNS, TLS, connection refused), so the fonts it declares could not be audited. | Make {stylesheet} reachable (last error: {error}) or remove it from the page, then re-run the audit. | A stylesheet that cannot be downloaded is likely failing for visitors too, leaving the page with the wrong fonts or unstyled. |
37A-WebFontAuditor-500 | ERROR | The audited page itself could not be fetched or returned a non-2xx status. | Verify {url} is reachable and returns HTTP 200, then re-run the audit. Last error was {error}. | β |
37A-WebFontAuditor-200 | SUCCESS | All rules passed. Also emitted when the page uses no web fonts. | β | β |
Every message quotes what was observed, for example: Font family "Inter" has 2 @font-face rule(s) without font-display in /css/site.css, so its text stays invisible while the font downloads. or Font file /fonts/inter.woff2 ("Inter") weighs 313 KB, above the 100 KB budget.
| Status | Description | Test logic |
|---|---|---|
| SUCCESS | Every web font rule passed, or the page uses no web fonts | No 300β308 and no 400β402 finding; one 200 check whose message lists the families, the number of @font-face rules judged and the largest font file. |
| WARNING | Text stays visible and fonts are WOFF2, but the setup can be leaner | No 400β402 finding, and at least one of: third-party font host (300), more than 2 families (301), 4 or more static files in a family (302), preload without crossorigin (303), more than 1 font preload (304), no fallback metric overrides (305), font file over 100 KB (306), unreadable stylesheet (307, 308). |
| FAIL | A font hides text while it loads, or is not served as WOFF2 | A used family has no font-display (400), uses block or auto (401), or has no WOFF2 source (402). The summary message is the first finding in that order. |
| ERROR | The auditor could not fetch the page | Network failure, invalid URL or non-2xx status on the audited URL (500). |
Without font-display, browsers hide text for up to three seconds while a font downloads. On a slow phone connection that is three seconds of a blank page.
swap shows the fallback font at once and swaps when the web font arrives. optional uses the web font only when it is already cached, which is the calmest choice for body text.
WOFF2 is the smallest font format and all current browsers support it; older formats are larger for no benefit.
Fonts on another host need a new DNS lookup, connection and TLS handshake, because font requests never reuse the connection that fetched the stylesheet.
A font preload without crossorigin is thrown away and the file is downloaded twice. Several preloads delay the stylesheets and images behind them.
Subsetting to the characters a site uses typically cuts a font file by 60β80%. One variable font file can replace four or more static weight files.
A fallback font with different metrics makes lines reflow when the web font arrives. A fallback @font-face tuned with size-adjust, ascent-override and descent-override keeps the text in place.
Fonts declared by JavaScript. Only CSS present in the HTML, in linked stylesheets and one level of @import is read. Styles injected at runtime are not seen.
Whether a CSS rule matches an element. A family counts as used when any CSS rule references it, even if that rule matches nothing on the page. Themes that define many font presets can therefore report more families than a visitor downloads.
Proof of subsetting. File size is the only signal: a file over 100 KB is reported, but the glyphs inside it are not inspected. A variable font with several axes can exceed the budget even when subsetted.
Legacy fallbacks after WOFF2. A src that lists WOFF2 first and older formats after it passes; the extra entries cost nothing in current browsers.
More than 20 font files or 30 stylesheets. Larger pages are sampled in document order.
Stylesheets and fonts on other hosts are requested without the page's Basic Auth credentials. Caching of font files is covered by the Cache Auditor, and compression by the Content Encoding Auditor.
This documentation is built and hosted on Mintlify, a developer documentation platform.
Add this auditor to your monitoring setup and start identifying issues on your websites today.