BlogDeploy

Google fonts alternatives for GDPR (and how to self host fonts)

Written by Codemzy on November 27th, 2024

Google Fonts might not be GDPR compliant. Here are two alternative options (hosted and self-hosted) you can use instead, and how to set them up on your website.

This post contains affiliate links. If you use these links, I may earn a commission (at no cost to you). I only recommend products I use myself that can help solve a specific problem.

I've been using Google Fonts on my websites for over 10 years. Before GDPR was a thing. And I never really gave it much thought. But a lot has changed in internet land in the last 10 years.

  • Digital privacy is a big deal now
  • Cookie banners are everywhere
  • GDPR compliance is a legal requirement

This has changed some of the services I use over the years. I'd removed Google Analytics to the GDPR-compliant and cookieless Fathom Analytics.

Often I don't track visitors, and track events anonymously instead.

And I try to avoid third-party cookies.

But I was still using Google Fonts. I had Google Fonts on this website until recently (thanks to the person on Twitter/X who pointed this out to me!). Because I honestly didn't realise it was a big deal.

It doesn't install cookies, and according to Google, it's not used to "create profiles of end users or for targeted advertising".

So what's the problem? Well, it turns out that Google Fonts breaches GDPR compliance because they collect the user's IP address to transmit fonts. And it's not Google who gets in trouble, it's the website using Google Fonts!

The ruling directs the website to stop providing IP addresses to Google and threatens the site operator with a fine of €250,000 for each violation, or up to six months in prison, for continued improper use of Google Fonts.

- The Register Website fined by German court for leaking visitor's IP address via Google Fonts

From a GDPR point of view, it kind of rules out Google Fonts. The (unlikely but terrifying) threat of prison is enough to consider the alternative options.

I came across two options:

  1. An easy switch to a GDPR-compliant alternative provider
  2. Self-hosting the fonts yourself

1. GDPR-compliant alternative

There are alternatives to Google Fonts you can use that state they are GDPR-compliant. My first choice is Bunny.net because I already use them for the CDN, storage, and video hosting - so I know they offer great services and super support!

And switching to Bunny Fonts is soooo simple.

You can replace the domains in your script tags, and it should work. It's a like-for-like replacement for the most part. Switching https://fonts.googleapis.com to https://fonts.bunny.net.

From this:

<link rel="preconnect" href="https://fonts.googleapis.com"> 
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet" />

To this:

<link rel="preconnect" href="https://fonts.bunny.net">
<link href="https://fonts.bunny.net/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet" />

Nice!

2. Self-host fonts

If you want to save users from fetching the fonts from another domain and have a bit more control of updates to font versions etc, you can self-host fonts instead.

Now this isn't quite as straightforward. To be honest, I almost gave up at one point. Because I had never even heard of the different font types (woff2, woff, eot, ttf) before this exercise. But if I can do it, so can you!

I started off downloading the fonts from Google. They come in ttf format. From my research, it seemed the font format I needed for modern(ish) browsers is woff2 and woff, as the files will be compressed and smaller (and therefore better for performance). I couldn't find an easy way to convert the downloads from Google, so instead I used this tool:

You can search for the font you need (like Poppins), and then I selected historic support to get the woff2 and woff formats.

Another tool I have used if I can only get the font I want in a different format is the FontSquirrel Webfont Generator. It can be a bit temperamental in my experience, but when it did work the optimal setting worked well for me.

Upload fonts to your CDN

Now you can upload the fonts to your server. Ideally, these assets should be on a CDN for speed and performance, as they are unlikely to change often.

You can host your fonts wherever you host other assets, like your images. You might not want the same setup as me, but I don't like to host larger files in my git repositories, so I popped my font files in my DigitalOcean Spaces bucket with a custom subdomain.

📁 assets/
└── 📁 fonts/
  ├── 📄 poppins-v21-latin-300.woff2
  └── 📄 poppins-v21-latin-300.woff

Once you've uploaded your font files somewhere, it's time to add some CSS.

Point your CSS to the hosted fonts

In the google-webfonts-helper tool we used earlier, you will find some CSS you can copy. You will find the CSS for whatever browsers you downloaded the font file for, and you can also update the URL. So if you hosted the assets on a subdomain, instead of ../fonts/ you might put https://assets.domain.com/fonts/.

I'm only going to upload woff2 and woff font files, so I'll also tweak the CSS to only include those font types.

/* poppins-100 - latin */
@font-face {
  font-display: swap;
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 100;
  src: url('../fonts/poppins-v21-latin-100.woff2') format('woff2'),
       url('../fonts/poppins-v21-latin-100.woff') format('woff');
}
/* poppins-300 - latin */
@font-face {
  font-display: swap;
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 300;
  src: url('../fonts/poppins-v21-latin-300.woff2') format('woff2'),
       url('../fonts/poppins-v21-latin-300.woff') format('woff');
}
/* poppins-regular - latin */
/* ... */

You can add this CSS to your main CSS files, or create a new fonts.css file to keep things separate.

Remove the Google Fonts script

Now you are self-hosting your fonts, you can remove the Google Fonts embed code from your website.

The scripts you are removing will look something like this:

<link rel="preconnect" href="https://fonts.googleapis.com"> 
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet" />

Now your fonts are hosted locally!