How to Self-Host Google Fonts in WordPress (Faster and More Private)

Why and how to self-host Google Fonts in WordPress: downloading WOFF2 files, writing @font-face, preloading, font-display, subsetting and removing the external requests.

To self-host Google Fonts in WordPress, download the WOFF2 files for only the families, weights and character subsets you use, upload them to your theme or child theme, declare them with @font-face using font-display: swap, preload the one or two fonts visible above the fold, and stop the theme and plugins from loading the copy from fonts.googleapis.com.

I moved my own site to self-hosted fonts and do the same on most client sites. Here is the process.

Why self-host Google Fonts?

Self-hosting removes connections to two extra domains (fonts.googleapis.com for the CSS and fonts.gstatic.com for the files), lets you control caching and preloading, and keeps visitor IP addresses from being sent to Google. Since browsers partitioned their caches, the old argument that “visitors already have Google Fonts cached” no longer applies.

Speed

With the Google-hosted version, the browser must fetch the HTML, discover the CSS link, connect to Google’s CSS domain, download the CSS, then connect to the font domain and download the files. Self-hosting turns that chain into requests on a connection already open to your own domain, and lets you preload the files.

Privacy

In January 2022, a regional court in Munich ruled that a website passing a visitor’s IP address to Google by embedding Google Fonts, without consent, violated the GDPR. Since then many European site owners self-host. If you serve European visitors, it is a sensible default; for legal specifics, ask a lawyer.

Step 1: decide what you actually need

Every weight and style is a separate file. Audit your design:

  • Which families? Ideally one or two.
  • Which weights? Often 400 and 700 are enough; perhaps 600 for headings.
  • Italics? Only if the design really uses them.
  • Which scripts? Latin, Latin-extended, Arabic? Load only the subsets your content needs.

Variable fonts can replace several static weights with one file, which is often smaller in total when you use three or more weights.

Step 2: download WOFF2 files

WOFF2 is supported by all modern browsers and is the most compressed web font format, so you rarely need anything else. Options:

  • Download the family from Google Fonts and convert, or
  • Use a helper tool that generates WOFF2 files and @font-face CSS for selected weights and subsets.

Check the font’s licence file; most Google Fonts use the SIL Open Font License or Apache License.

Step 3: add the files to your theme

Put them in your child theme, for example assets/fonts/, so theme updates do not remove them. Then declare:

@font-face {
  font-family: "Inter";
  src: url("../fonts/inter-latin-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F;
}
@font-face {
  font-family: "Inter";
  src: url("../fonts/inter-latin-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

unicode-range lets the browser download a subset only when the page contains those characters, which matters for bilingual Arabic and English sites.

Step 4: preload the critical fonts

Preload only fonts used in the first screen, typically the body font regular weight and maybe the heading weight:

add_action( 'wp_head', function () {
    printf(
        '<link rel="preload" href="%s" as="font" type="font/woff2" crossorigin>' . "n",
        esc_url( get_stylesheet_directory_uri() . '/assets/fonts/inter-latin-400.woff2' )
    );
}, 1 );

The crossorigin attribute is required for font preloads, even on the same domain, otherwise the browser downloads the font twice. Preloading too many fonts competes with your LCP image.

Step 5: remove the Google-hosted copies

This is the step people forget. Check the page source for fonts.googleapis.com and fonts.gstatic.com. Sources include:

  • The theme’s typography settings (many themes have a “load fonts locally” option).
  • Page builders’ global font settings.
  • Plugins such as sliders, forms or maps that enqueue their own fonts.

Dequeue them by handle if no setting exists:

add_action( 'wp_enqueue_scripts', function () {
    wp_dequeue_style( 'some-plugin-google-fonts' );
}, 100 );

Remember to remove any preconnect hints to Google font domains once nothing loads from them.

Step 6: caching

Fonts rarely change, so serve them with long cache lifetimes (Cache-Control: public, max-age=31536000, immutable) and change the filename or version when you update them. Make sure your CDN respects these headers.

Reducing layout shift from font swaps

font-display: swap avoids invisible text but can cause a visible jump when the web font replaces the fallback, which affects CLS. Reduce it with:

  • A fallback font with similar proportions.
  • size-adjust, ascent-override and descent-override on a fallback @font-face, to match the metrics of your web font.

Arabic fonts

Arabic font files are usually larger because they contain more glyphs and contextual forms. Subset aggressively, load fewer weights, and test legibility on small screens. See the Arabic ecommerce checklist.

Checklist

  • Families, weights and subsets reduced to what is used
  • WOFF2 files in the child theme
  • @font-face with font-display: swap
  • One or two critical fonts preloaded with crossorigin
  • No requests left to Google font domains
  • Long cache headers on font files
  • Fallback metrics tuned to limit layout shift

Common mistakes

  • Self-hosting all eighteen weights “just in case.”
  • Preloading fonts that are not used on the page.
  • Leaving a plugin that still loads the Google-hosted version.
  • Forgetting crossorigin on preload.

Need help speeding up your theme’s assets? Get in touch. Next: reducing Total Blocking Time.

Frequently asked questions

Is it legal to self-host Google Fonts?

Google Fonts are released under open licences, mostly the SIL Open Font License, which allows self-hosting. Check the licence of each font family you use.

Are self-hosted fonts faster than Google Fonts?

Usually, because the browser avoids connecting to additional domains, and modern browsers no longer share cached fonts between sites. The difference depends on your hosting and setup.

Does self-hosting help with GDPR?

Loading fonts from Google sends visitors' IP addresses to Google. A 2022 German court ruling found this problematic without consent, so many European sites self-host fonts. This is not legal advice.

What is font-display swap?

It tells the browser to show text immediately in a fallback font and swap to the web font when it loads, avoiding invisible text.

Muhamed Ahmed

Ecommerce & Web Solutions Developer

I'm Muhamed Ahmed, an ecommerce and web solutions developer with 15 years of experience building fast, secure online stores and websites on WooCommerce, WordPress and custom Laravel platforms. I write about website speed, SEO, automation and conversion.

All articles Work with me

Related articles