DEV Community

Muhammad Usman
Muhammad Usman

Posted on • Originally published at pixicstudio.Medium

Why I Switched From Google Fonts CDN to Self-Hosting (and Never Looked Back)

Google Fonts might look easy, but they're quietly slowing your site down.


(Original screenshot timestamped July 29, 2025)

Most WordPress sites blindly load Google Fonts from the CDN. It's easy. It's fast. But it's not the best move, especially if you care about performance, control, and user privacy of your website.

Here's how I ditched the external requests and self-hosted Google Fonts properly on my WordPress site. I'll walk you through my exact setup in detail. Downloading and converting fonts to applying them with @font-face and CSS variables.

My mobile PageSpeed score jumped from 66 to 94. And if you've ever tried optimizing for mobile, you already know, that's not easy.

Please note that, score may vary depend on server you are testing, but no too much.

Why Self-Host Google Fonts?

Before you learn how to host Google fonts locally, let's get into why we should host them locally:

  • Better performance: There will be fewer external requests, that means faster load time.
  • Full control on Font-display: No layout shift. Fonts load predictably.
  • Privacy: No calls to Google servers, GDPR-compliant.
  • Design consistency: Always the exact version. No silent updates.

Let's go through with the technical steps.

Step 1: Download Fonts from Google Fonts

I picked Inter and Mulish, both available as variable fonts files directly from fonts.google.com, according to my project requirements.
Downloaded the full .ttf files (including italic versions) directly.

Step 2: Convert to .woff2 Format

I used a free .ttf to .woff2 convertor to convert .ttf files to .woff2.

Why did I choose .woff2 format for my fonts?

  • It's the smallest modern web font format.
  • Great compression.
  • Wide browser support.

Step 3: Create a Custom Fonts Folder on WordPress directory

Inside my WordPress installation:

/wp-content/fonts/
Enter fullscreen mode Exit fullscreen mode

I placed these files:

  • Inter-VariableFont_opsz,wght.woff2
  • Inter-Italic-VariableFont_opsz,wght.woff2
  • Mulish-VariableFont_wght.woff2
  • Mulish-Italic-VariableFont_wght.woff2

I host them directly, so they're served from my domain server, not Google's.

Step 4: Register Fonts with @font-face in CSS

In my theme's main stylesheet (style.css), I added:

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/wp-content/fonts/Inter-VariableFont_opsz,wght.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/wp-content/fonts/Inter-Italic-VariableFont_opsz,wght.woff2') format('woff2');
}
@font-face {
  font-family: 'Mulish';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/wp-content/fonts/Mulish-VariableFont_wght.woff2') format('woff2');
}
@font-face {
  font-family: 'Mulish';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/wp-content/fonts/Mulish-Italic-VariableFont_wght.woff2') format('woff2');
}
Enter fullscreen mode Exit fullscreen mode

Note the use of:

  • font-display: swap for better performance.
  • Variable weights from 100 to 900, one file covers all styles.

Step 5: Define CSS Variables for Font Management

At the root level to my styles, I declared these:

:root {
  --font-inter: "Inter", sans-serif;
  --font-mulish: "Mulish", sans-serif;
  --font-weight-extra-light: 200;
  --font-weight-regular: 400;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
}
Enter fullscreen mode Exit fullscreen mode

Makes it easier to swap fonts or weights site-wide.

Step 6: Apply Fonts in CSS Like a Pro

My base typography setup:

html {
  font-optical-sizing: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
body {
  font-family: var(--font-mulish);
  font-weight: var(--font-weight-regular);
}
h1, h2, h3, h5, h6 {
  font-family: var(--font-inter);
  font-weight: var(--font-weight-bold);
}
a {
  font-family: var(--font-inter);
  text-decoration: none;
}
Enter fullscreen mode Exit fullscreen mode

Clean, consistent, and easy to manage.


Final Result: A Faster, Cleaner WordPress Frontend

After self-hosting my fonts:

  • Font requests went from 4+ to 0 external
  • CLS (Cumulative Layout Shift) dropped
  • PageSpeed Insights scored higher
  • Typography is now fully under my control

No plugins. No CDN dependencies. Just clean code and the best performance.

After making these changes, my mobile PageSpeed score jumped from 66 to 94, and for desktop, you already know it's 100.

(Original screenshot timestamped July 29, 2025) Complete Report here:
https://pagespeed.web.dev/analysis/https-www-curemed-co/27yura3l04?form_factor=desktop

If you've done mobile optimization before, you know this isn't just a small achievement, especially without using any cache/speed plugin, it's a major one. Fonts are one of the biggest contributors to render delay, and removing Google CDN from the equation really made a huge difference in performance.


Pro Tips

  • Serve font files with proper headers (woff2 should be font/woff2).
  • Preload critical fonts for faster rendering:
<link rel="preload" href="/wp-content/fonts/Inter-VariableFont_opsz,wght.woff2" as="font" type="font/woff2" crossorigin="anonymous">
Enter fullscreen mode Exit fullscreen mode
  • Avoid too many weights. Variable fonts let you load everything in one file.
  • You can use this setup almost with anything, even it is not a WordPress.

Wrap-Up

If you're serious about frontend performance on WordPress or any other project, self-hosting Google Fonts is really a must-do move.

It's not just a speed hack. It's about owning your assets, reducing dependencies, and building a better user experience.

And yes, it's dead simple, once you know what you're doing.

Want to try it yourself?
Skip the plugins. Take control. Your users (and Core Web Vitals score) will thank you.

Top comments (0)