Signatur
Beschreibung
window.queryLocalFonts() gehört zur Local Font Access API. Damit fragt eine Webanwendung die Schriftarten ab, die auf dem Gerät des Nutzers installiert sind. Jede Schrift wird als FontData-Objekt geliefert, mit den Eigenschaften postscriptName, fullName, family und style. Über die Methode blob() lassen sich außerdem die rohen Bytes der Schriftdatei (SFNT) auslesen.
Gedacht ist die API vor allem für professionelle Werkzeuge im Browser: Grafik- und Designprogramme, Textverarbeitungen oder Präsentationsprogramme. Dort sollen Nutzer ihre lokal installierten Schriften auswählen, genau wie in einer Desktop-Anwendung. Ohne diese API bleibt nur CSS mit local(), und damit kann man verfügbare Schriften weder auflisten noch ihre Dateien lesen.
Die Methode steht nur in einem sicheren Kontext (HTTPS) zur Verfügung. Der Aufruf braucht eine vorübergehende Nutzeraktivierung, zum Beispiel einen Klick. Beim ersten Aufruf fragt der Browser außerdem die Berechtigung local-fonts ab. Lehnt der Nutzer ab oder verbietet die Permissions Policy den Zugriff, wird das Promise abgelehnt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $options | Object | {} | Optionales Konfigurationsobjekt. |
| $options.postscriptNames | string[] | Liste von PostScript-Namen, nach denen gefiltert wird. Zurückgegeben werden nur Schriften, deren postscriptName in der Liste steht, z. B. ['Verdana', 'Verdana-Bold']. |
Rückgabewert
FontData-Objekten erfüllt wird. Ist keine Schrift verfügbar oder passt kein Filtername, ist das Array leer. Wird die Berechtigung verweigert, lehnt das Promise mit einem DOMException vom Typ NotAllowedError ab. Fehlt die Nutzeraktivierung, kommt je nach Browser ein SecurityError.Beispiele
Alle lokalen Schriftarten nach Klick auflisten
const button = document.querySelector('#fonts-laden');
button.addEventListener('click', async () => {
if (!('queryLocalFonts' in window)) {
console.warn('Local Font Access API wird nicht unterstützt.');
return;
}
try {
const fonts = await window.queryLocalFonts();
for (const font of fonts.slice(0, 3)) {
console.log(font.postscriptName, '|', font.family, '|', font.style);
}
console.log(`Insgesamt ${fonts.length} Schriften gefunden.`);
} catch (err) {
console.error(`${err.name}: ${err.message}`);
}
});
Schriftfamilien für ein Auswahlmenü gruppieren
const select = document.querySelector('#font-auswahl');
document.querySelector('#laden').addEventListener('click', async () => {
const fonts = await window.queryLocalFonts();
// Doppelte Familien entfernen, alphabetisch sortieren
const families = [...new Set(fonts.map((f) => f.family))]
.sort((a, b) => a.localeCompare(b, 'de'));
select.replaceChildren(
...families.map((family) => new Option(family, family))
);
select.addEventListener('change', () => {
document.querySelector('#editor').style.fontFamily = `"${select.value}"`;
});
console.log(`${families.length} Familien geladen`);
});
Bestimmte Schriften filtern und Format prüfen
document.querySelector('#pruefen').addEventListener('click', async () => {
const fonts = await window.queryLocalFonts({
postscriptNames: ['Verdana', 'Verdana-Bold'],
});
for (const font of fonts) {
const blob = await font.blob();
// Die ersten 4 Bytes geben das Format an
const tag = await blob.slice(0, 4).text();
const format =
tag === 'OTTO' ? 'OpenType (CFF)' :
tag === 'true' || tag === '\x00\x01\x00\x00' ? 'TrueType' :
'unbekannt';
console.log(`${font.fullName}: ${format}, ${blob.size} Bytes`);
}
});
Berechtigungsstatus vorab abfragen
const status = await navigator.permissions.query({ name: 'local-fonts' });
console.log('Berechtigung:', status.state);
status.addEventListener('change', () => {
console.log('Neuer Status:', status.state);
});
// Wichtig · Fallstricke
- Browser-Unterstützung: Die Methode gibt es nur in Chromium-Browsern ab Version 103 auf dem Desktop. Firefox und Safari unterstützen sie nicht. Prüfe deshalb immer vorab mit
'queryLocalFonts' in window. - Nutzeraktivierung nötig: Beim ersten Aufruf braucht es eine Nutzeraktion, etwa einen Klick. Ein Aufruf direkt beim Laden der Seite scheitert.
- Nur sicherer Kontext: Die Methode funktioniert nur über HTTPS oder
localhost. In iframes muss sie per Permissions Policy freigegeben sein, z. B. mitallow="local-fonts". - Datenschutz: Die Liste installierter Schriften eignet sich gut für Browser-Fingerprinting. Deshalb ist die API an eine Berechtigung gebunden. Frage den Zugriff nur ab, wenn der Nutzer ihn wirklich braucht, und begründe ihn in der Oberfläche.
- Leeres Ergebnis: Unbekannte Namen in
postscriptNameslösen keinen Fehler aus. Sie fehlen einfach im Ergebnis-Array. - Lizenzen:
blob()liefert die rohe Schriftdatei. Bevor du sie weiterverarbeitest oder hochlädst, prüfe die Lizenzbedingungen der jeweiligen Schrift. - Leistung: Auf Systemen mit vielen Schriften kann das Array Hunderte Einträge haben. Das Einlesen der Dateien per
blob()kostet Speicher, deshalb solltest du Blobs nur bei Bedarf laden.