Schriften in Next.js selbst hosten, und warum das in Deutschland zählt
Im Januar 2022 hat das Landgericht München entschieden, dass das übliche Einbinden von Google Fonts per <link> auf fonts.googleapis.com die IP-Adresse des Besuchers ohne Einwilligung an ein US-Unternehmen übermittelt, und dass das eine Verletzung seiner Rechte ist. Danach kam die Abmahnwelle. Tausende Seitenbetreiber bekamen Post mit der Bitte um hundert Euro und eine Unterschrift. Die meisten wussten gar nicht, dass ihre Seite diese Anfrage überhaupt macht, weil eine Schrift zu den Dingen gehört, die man einmal einrichtet und nie wieder anschaut.
Die Lösung ist nicht, die Schriften wegzulassen. Die Lösung ist, sie selbst auszuliefern. Seit Next.js 13 ist das ein Import.
Was next/font macht
next/font/google lädt die Schriftdateien während next build herunter, legt sie in dein statisches Output und erzeugt die @font-face-Regeln, die auf deinen eigenen Server zeigen. Zur Laufzeit fragt der Browser nur noch bei dir nach. Google ist beim Build beteiligt, auf deinem Rechner oder deinem CI-Runner, nie im Browser des Besuchers.
// app/layout.tsx
import { Inter } from "next/font/google";
const inter = Inter({
subsets: ["latin", "latin-ext"],
display: "swap",
variable: "--font-sans",
});
export default function RootLayout({ children }) {
return (
<html lang="de" className={inter.variable}>
<body>{children}</body>
</html>
);
}
Drei Kleinigkeiten, die in diesem Block stimmen sollten. subsets legt fest, welche Zeichenbereiche gebündelt werden. Für Deutsch reicht latin, aber sobald du einen polnischen oder türkischen Namen schreibst, bist du froh über latin-ext. display: "swap" zeigt den Text in einer Ersatzschrift, bis die echte da ist, und hält die Seite auf einer langsamen Verbindung lesbar. Die CSS-Variable lässt dich die Schrift aus normalem CSS heraus ansprechen, ohne noch etwas zu importieren. Das zählt, wenn du wie ich ohne Tailwind arbeitest.
Wenn du eine Schrift gekauft hast statt eine freie zu nehmen, macht next/font/local dasselbe aus einer Datei in deinem Repo. Gleiche API, gleiche Behandlung beim Build.
Wie du prüfst, ob es wirklich greift
Vertrau dem Import nicht. Öffne die fertige Seite, öffne den Netzwerk-Tab, filtere nach "font", lade neu. Jede Schriftanfrage muss an deine eigene Domain gehen. Wenn irgendwas auf fonts.googleapis.com oder fonts.gstatic.com zeigt, lädt noch etwas anderes auf der Seite Schriften auf die alte Art. Die üblichen Verdächtigen: ein Widget von Dritten, ein altes globales Stylesheet mit einer @import-Zeile ganz oben, oder eine Komponentenbibliothek, die ihren eigenen Font-Link mitbringt.
Schneller geht es im Terminal: das HTML der Seite mit curl holen und nach googleapis greppen. Null Treffer ist das Ziel.
Warum ich das auch auf einer englischen Seite mache
Die Seite, die du gerade liest, ist standardmäßig Englisch mit einem deutschen Spiegel. Das rechtliche Risiko betrifft nur die deutschen Besucher, aber es gibt keinen Grund, zwei Schriftstrategien zu fahren. Selbst hosten ist außerdem schneller: ein DNS-Lookup weniger, ein TLS-Handshake weniger, und die Schrift kommt vom selben CDN-Knoten wie die Seite. Es ist der seltene Fall, in dem die datenschutzrechtlich richtige Option auch die schnellere ist. Da gibt es nichts abzuwägen.
