Many WordPress themes and page builders load fonts from fonts.googleapis.com and fonts.gstatic.com. That costs extra DNS lookups and connections to third-party servers, and in the EU a German court ruled in 2022 that embedding Google Fonts remotely transmitted visitors’ IP addresses without consent. Hosting the fonts on your own server fixes both: fewer connections, and no data sent to Google for fonts.
1. Find which fonts are loaded
Open the site, then open DevTools → Network → filter by “font” (and by “css” for fonts.googleapis.com). Or from the command line:
curl -s https://example.com | grep -oE 'fonts\.(googleapis|gstatic)\.com[^"'"'"' )]*' | sort -u
Also check every page type (blog post, shop, forms): some plugins (sliders, forms, maps) load their own fonts.
2. Self-host the fonts
Option A: WordPress Font Library (block themes, WP 6.5+)
In the Site Editor → Styles → Typography → Manage fonts, install Google Fonts. WordPress downloads them to your server (wp-content/fonts/) instead of loading them remotely. Then remove any theme or plugin code that still enqueues the remote stylesheet.
Option B: a plugin
Plugins such as OMGF (Optimize My Google Fonts), or the local-fonts option in performance plugins (Perfmatters, WP Rocket’s “self-host Google Fonts”, LiteSpeed Cache’s font settings) detect Google Fonts requests, download the files, and rewrite the CSS to load them locally. That’s the quickest route for classic themes and page builders.
Elementor: Elementor → Settings → Performance → Google Fonts: Load locally (in recent versions).
Option C: manually (most control)
- Download the fonts as WOFF2 (google-webfonts-helper, or the font’s GitHub repository). Only download the weights and styles you actually use (e.g. 400, 600, 700). Each weight is a separate file.
- Upload them to your child theme, e.g.
wp-content/themes/child/fonts/. - Add
@font-facerules to the child theme’s CSS:
@font-face {
font-family: 'Inter';
src: url('fonts/inter-v13-latin-regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Inter';
src: url('fonts/inter-v13-latin-700.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}
- Stop the theme from loading Google Fonts. Many themes have a setting. Otherwise dequeue the stylesheet handle in the child theme’s
functions.php:
add_action('wp_enqueue_scripts', function () {
wp_dequeue_style('theme-google-fonts'); // find the handle in the page source (id="…-css")
}, 20);
3. Make fonts load fast
- WOFF2 only, which every modern browser supports.
- Subset to the character sets you need (e.g. Latin). Smaller files load faster.
font-display: swapshows text immediately in a fallback font, which avoids invisible text and helps Core Web Vitals.- Preload the one or two fonts used above the fold:
<link rel="preload" href="/wp-content/themes/child/fonts/inter-v13-latin-regular.woff2" as="font" type="font/woff2" crossorigin>
(Add it via wp_head, or your performance plugin’s preload setting.)
- Consider system font stacks (
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;) for body text. They’re zero download and instant.
See Core Web Vitals and server speed.
4. Cache headers for font files
Fonts rarely change. Let browsers cache them for a long time. In Nginx:
location ~* \.(woff2?|ttf|otf)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
If fonts are served from a different subdomain or CDN, add CORS (Access-Control-Allow-Origin), because fonts require it. See Nginx static file caching and CORS explained.
5. Verify
- DevTools → Network: no requests to
fonts.googleapis.comorfonts.gstatic.comon any page. - The page still looks right: correct weights, no fallback fonts where you expect the custom one.
- Run PageSpeed Insights or Lighthouse again, and compare the “reduce third-party” and LCP results.
Same idea for other third parties
Locally hosting icons (Font Awesome), and avoiding unneeded third-party scripts, improves speed and privacy too. Every external origin costs a DNS lookup, a TCP connection and a TLS handshake. See website speed optimization.
Quick reference
| Task | How |
|---|---|
| Find remote fonts | DevTools Network, or curl … | grep fonts.g |
| Block themes | Site Editor → Manage fonts (stored locally) |
| Classic themes | OMGF or a performance plugin’s local fonts option |
| Manual | WOFF2 files + @font-face + dequeue remote CSS |
| Speed | font-display: swap, preload, subset, long cache |
Related: WordPress cache plugins and WordPress on a VPS.