Skip to content

Oliver's Blog

Using Google Fonts in a GDPR compliant way

  • web fonts
  • CSS
  • GDPR
  • privacy

When using Google Fonts the default way you transfer personal data of your visitors to Google. This is problematic. I'll explain why and how to use Google Fonts in an unproblematic way.

TL;DR: If you are not interested in the background, you can jump right to the "How to use Google Fonts in a GDPR compliant way" section.

Since the GDPR is in force, I as a web developer have been trying to find out what impact this has on my work. One question I haven't had an answer to for a long time is if I can use web fonts from Google Fonts, Typekit or other services without needing the consent of the user for this.

Recent ruling of a German court shows that you need the consent of a user before loading fonts from Google Fonts. So web fonts are not seen as technically necessary or as legitimate interest of the website operator.

Disclaimer: I'm not a lawyer and what I write here is no legal advice. It's my point of view as of the day of writing this. It may be subject of change, especially due to rulings of DPAs and courts regarding this subject. I'm not responsible for any actions you take based on what I wrote here.

What is privacy?

The core of everything I write in this blog post refers to privacy. To me, privacy is an important and valuable concept. It's about Informational self-determination which means, that one can decide themself what personal data is made available to whom. In this blog post I want to focus on privacy on the WWW even though it's equally important in other fields of life.

What's the deal with privacy and websites?

One may think that if you don't have any forms or tracking on your website that you don't process any personal data. Therefore you don't need to care about anything related to privacy and that's it. But that's not true. It's more or less impossible to have a website and not process personal data. But let's take this step by step.

When talking about privacy, it's always about personal data. Article 1 of the GDPR:

This Regulation lays down rules relating to the protection of natural persons with regard to the processing of personal data and rules relating to the free movement of personal data.

But what is personal data? For the GDPR it's defined in Article 4:

‘personal data’ means any information relating to an identified or identifiable natural person (‘data subject’); an identifiable natural person is one who can be identified, directly or indirectly, in particular by reference to an identifier such as a name, an identification number, location data, an online identifier or to one or more factors specific to the physical, physiological, genetic, mental, economic, cultural or social identity of that natural person;

So besides obviously personal data which you may collect through a form (name, email address, address, ...) the IP address is also seen as personal data. One may be identified through an IP address. It's not about how easy it is and who is able to do this, the possibility alone is enough to count an IP address as personal data.

To understand what impact this has when creating a website, one needs to have a basic understanding of how the WWW and internet work.

How the WWW works. Or: Why it is impossible to not process personal data on websites.

Let's keep it simple: when visiting a website (for example your browser will find out on which server this website is hosted. It will connect to this server and ask for the contents of the webpage. The server then sends the contents over and the browser will show you the webpage.

To use the internet you need to have an IP address. Usually you won't need to care about this since you will get one when you connect to the internet. This IP address is necessary for the server to know where to send the contents to. Only you can have this specific IP address at this moment. Therefore it's personal data. You can be identified by it.

A website can consist of many different types of contents. Text, images, scripts, styles and many more. Those contents don't need to be stored at the same server. When receiving the data from the server the browser may get information to load certain contents from other servers as well. So the browser connects to those as well and then your IP address (and therefore personal data) will be sent to other servers as well.

As a user you usually don't know where the contents are loaded from in the background. It's easy to find out with the developer tools built into the browser though. So the one responsible for the website is also responsible to inform the visitors of the webpage which other services are used on the website. Depending on where the services are located it may only be necessary to inform the users about it (in the privacy statement) or even get the active consent before establishing a connection to this service.

Server logs

When connecting to a server, the IP address (and other data) usually gets stored in the server logs. So the server keeps record of what IP address requests which resource at what time. On the one hand those logs are essential when investigating errors and hacks but can also be used for tracking users. Server logs are usually seen as technical necessary.

Those server logs are the reason why you need to name your hosting provider (if applicable) in the privacy statement. You should also write about how long the log files are stored.

As far as I know, there is no ruling about the question how long one is allowed to store the logs yet. There are different things to consider regarding this, but I won't go into detail about it here.

What is the GDPR

I have been referencing the GDPR a lot already, here some basics you should know about it.

GDPR is an abbreviation for General Data Protection Regulation. It's a regulation in EU law and came into force in 2018. It's binding and applicable by all EU member states as well as the members of the "European Economic Area".

Not everything written in the GDPR is relevant for someone building a small website. But there are some key points which are relevant for this blog post:

Privacy by Design

Article 25 is called "Data protection by design and by default". This means that you have to build your website in a way that the personal data of the users is protected by default. For example: the user doesn't have to "opt-out" of tracking but can only "opt-in". 

"Insecure Third Countries"

In Article 45 of the GDPR the transfer of personal data to third countries is explained:

A transfer of personal data to a third country or an international organisation may take place where the Commission has decided that the third country [...] ensures an adequate level of protection. Such a transfer shall not require any specific authorisation.

This means when using services outside the EU you need to ask the users for their consent before transferring personal data. Unless an "adequate level of protection" is ensured. For the US, this "adequate level of protection" is not ensured. Therefore you can't use any Google services, YouTube videos or so on your website without informing the user about the data transfer and getting a consent for it.

Cookie/Consent banners

Getting a consent for processing and transferring data is often done via a so-called "cookie banner" or "consent banner". On many websites a box appears having text and buttons. The text should inform you about why you are asked for a consent and what the effect will be. There should also be a link to the privacy statement where you can read about it in detail. The buttons should give the options to reject or consent.

Cookies are different from the transfer of personal data I have been writing about. On many websites you get informed about cookies but not about what other services you are connected to.

The issue with web fonts from external services

So if you want to use web fonts from Google Fonts directly, you need to inform the visitor about it and get a consent for it. You can't use the web font before this and therefore may use a fallback font. When the user gives the consent, you may load the web fonts and then those will be applied. This will lead to a change of the text styling and usually isn't something one would like to happen.

Or the user doesn't give their consent and the web font won't be loaded. The fallback font will be used instead. If you are fine with that, maybe you won't need the web font in the first place...

How to use Google Fonts in a GDPR compliant way

It's very simple to use Google Fonts. You visit their website, choose one or several fonts and get some code snippets you add to your HTML and CSS code. The downside of it is, that those fonts get loaded from Googles servers.

All the fonts you can find on the Google Fonts website are open-source and free. This means that you may find the .woff2 files you need to self-host through other sources as well. Many of them are on GitHub and can be download there. Some basic knowledge of CSS will be needed to implement it though.

Another option is to use the google-webfonts-helper by Mario Ranftl. You will find all Google Fonts there, can choose which styles you need and simply download the files you need to self-host. You also get the necessary CSS code.

Here's a step-to-step guide on how to use the google-webfonts-helper:

0. Visit the google-webfonts-helper website and search for font

The tool I'm suggesting is available under All the fonts are listed on the left side of the page. You can use the input on the top to filter for a specific font.

Webfonts helper 1

1. Select charsets

After clicking a list item on the left you will see some kind of details page for this web font. The options you will see under "1. Select charsets" and "2. Select styles" will vary depending on the font. For some fonts there will be many different charsets and styles available. For others there may be only one option.

When choosing the charset you need to consider what characters you will use. Will it only be Latin characters or maybe Cyrillic as well? You could simply choose all available options, but this would lead to a bigger file size and therefore a performance drawback.

2. Select styles

It's also about performance considerations when it comes to selecting styles. Choose only those you really need.

Webfonts helper 2

3. Copy CSS

At the time of writing there are two options: "Best Support" and "Modern Browsers". The difference between the two options is what files will be in the download. In 2022 there is no need to select "Best Support" since even IE9 supports .woff files. Only Opera Mini doesn't support .woff. But it doesn't support any of the other formats either. Just use a fallback when setting the font-family.

In 2022, the "modern" option isn't so modern any longer. All browsers which are relevant to me support in 2022 support woff2. So I only use woff2 files. One advantage of woff2 over woff is a smaller file size.

The last step before downloading the files is to change the path. In the gray box you can see the code snippets to copy into your CSS file. But for it to work you need to set the path inside src: [...] url('xxx') correctly.

I usually put the web fonts in a folder called "webfonts" inside an "assets" folder. When changing the path in the input, the CSS snippets above will adapt to it immediately.

The next step is to copy the CSS code from the google-webfonts-helper website into your CSS file. At this point I remove the line(s) for the woff files and only leave the local('') and url('...woff2').

Webfonts helper 3 Webfonts helper 4

Leaving the "local()" part in only makes sense if you fill in the name of the font it has when installed locally. The browser will first look if the font with the provided name is installed on the machine. If yes, it uses this font. If not, it will try the next source, in my case the url to the woff2 webfont.

@font-face {
  font-family: 'Amiri';
  font-style: normal;
  font-weight: 400;
  src: local('Amiri-Regular'),
  url('/assets/webfonts/amiri-v24-latin-regular.woff2') format('woff2');

@font-face {
  font-family: 'Amiri';
  font-style: italic;
  font-weight: 400;
  src: local('Amiri-Italic'),
  url('/assets/webfonts/amiri-v24-latin-italic.woff2') format('woff2');

4. Download files

Next you can download the files and copy them in the path you have set before.

What's left to do is to actually use the font-family in your CSS code.

body{ font-family: 'Amiri', serif; }