How to Use Google Fonts the Right Way
Google Fonts serves open-licence type to a majority of the web, free, with no signup. It's also casually misused on most of the sites that embed it — too many weights, inefficient markup, and unexamined privacy defaults. Here's the full walkthrough, from picking a font to shipping it responsibly.
What Google Fonts actually is
A directory of ~1,800 font families, all under open licences (overwhelmingly the SIL Open Font License), plus a serving infrastructure: a CSS API (fonts.googleapis.com) that returns @font-face rules tailored to the requesting browser, and a file CDN (fonts.gstatic.com). Because the licences are open, everything is free for commercial use, and — importantly — you may download any font and self-host it. The directory and the delivery method are separate decisions. (Licence details in our licensing guide.)
Step 1: choose like a professional
Browse with a job description, not a mood (our web font picks and pairing tool shortcut this). On a specimen page, before falling in love, check: the full weight range you need exists; true italics exist if body text needs them; the language coverage tab includes your markets; and the type tester at your sizes — everything looks good at 64px.
Step 2: request only what you use
Every selected style adds a file. The classic mistake is embedding six weights "to be safe" — each unused weight is dead kilobytes on every page view. A content site needs roughly: body 400, body italic, 700 for bold, and one heading weight. The URL syntax carries your choices:
<!-- static weights: regular + bold + italic 400 -->
https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,700;1,400&display=swap
<!-- variable range: whole weight axis in one file -->
https://fonts.googleapis.com/css2?family=Inter:[email protected]&display=swap
The 100..900 range syntax requests the variable version — one file covering every weight, usually the right call when you use three or more. Note display=swap in the URL: it sets font-display: swap so text renders in a fallback instantly instead of going invisible.
Step 3: embed efficiently
<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=Inter:[email protected]&display=swap"
rel="stylesheet">
Three rules: use the <link> in <head>, not CSS @import (import serialises the requests and delays fonts badly); keep the two preconnect hints (they warm up both domains in parallel); and combine all families into one URL — ?family=Inter…&family=Lora… — rather than multiple link tags. Then declare sensible fallbacks in CSS: font-family: "Inter", system-ui, sans-serif;.
Step 4: decide — CDN or self-host?
The old argument for the CDN ("it's probably cached from other sites") died when browsers partitioned caches per-site in 2020. Today the comparison is:
- CDN: zero setup, automatic per-browser optimisation and subsetting, fonts update silently. Cost: a third-party connection, and a privacy question (below).
- Self-hosting: one fewer origin, full caching control (
immutable, long max-age), immunity to third-party outages or blocking (Google domains are blocked in some countries), no data flows to Google. Cost: you manage the files and subsets yourself.
The tooling gap has closed: google-webfonts-helper downloads ready-made WOFF2 packages with @font-face CSS, and Fontsource ships every Google font as an npm package. For anything beyond a hobby page, self-hosting is our default recommendation — see Web Font Performance for the preload/fallback details that pair with it.
The GDPR question, plainly
When a visitor's browser fetches a font from Google's servers, Google necessarily receives their IP address. In January 2022, a Munich court ruled that embedding Google Fonts via the CDN without consent violated the GDPR, because that IP transfer happens before any consent is gathered. The decision (of a regional court, and much-debated) triggered a wave of warning letters in Germany and pushed much of the EU web to self-host. Google states that Fonts requests aren't used for profiling and aren't correlated with other Google data — but the legal exposure question is separate from the trust question. Practical guidance: if you have EU traffic, self-host; it eliminates the issue entirely and is faster anyway. This site currently uses the CDN and discloses it in the privacy policy; when it moves to production hosting, self-hosting is the plan.
The five classic mistakes, collected
- Six weights, two used. Audit your CSS; request what appears in it.
- Multiple
<link>tags / @import chains. One combined URL, in the head. - No
display=swap— invisible text on slow connections. - No fallback stack —
font-family: "Poppins"full stop, so a failed load means the browser's default serif. - Forgetting the font is a dependency. Families occasionally get updated metrics or renamed versions (Source Sans Pro → Source Sans 3). Self-hosting pins your version; CDN users should re-test occasionally.
A complete, copyable setup
<!-- head -->
<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=Fraunces:wght@600;700&family=Inter:[email protected]&display=swap" rel="stylesheet">
/* css */
h1, h2, h3 { font-family: "Fraunces", Georgia, serif; }
body { font-family: "Inter", system-ui, sans-serif; }
Two families, minimal weights, swap behaviour, real fallbacks — the whole quality gap between the average Google Fonts embed and a professional one is those four decisions. They take five minutes, once you know they exist. Now you do.