Signatur
Beschreibung
navigator.contacts ist der Einstiegspunkt der Contact Picker API. Die Eigenschaft gibt ein ContactsManager-Objekt zurück. Dessen Methode select() öffnet einen systemeigenen Auswahldialog, in dem der Nutzer einen oder mehrere Kontakte auswählt. Die Web-App bekommt nur die Felder zu sehen, die sie angefordert hat, und nur von den Kontakten, die der Nutzer ausdrücklich ausgewählt hat. Mit getProperties() fragt man ab, welche Felder die Plattform unterstützt.
Typische Einsatzfälle sind Formulare, in denen eine Telefonnummer oder E-Mail-Adresse aus dem Adressbuch übernommen werden soll, etwa beim Versenden einer Einladung, beim Teilen einer Rechnung oder beim Anlegen von Empfängern in Messaging- und Banking-Apps. Anders als bei einer vollständigen Synchronisierung des Adressbuchs sieht die Seite nie die ganze Kontaktliste. Das macht die API datenschutzfreundlich.
Die API ist nur in einem sicheren Kontext (HTTPS) verfügbar, nur im Top-Level-Browsing-Kontext und nur nach einer Nutzeraktion (z. B. einem Klick). Weil sie bisher fast nur in Chromium-Browsern unter Android läuft, sollte man ihr Vorhandensein immer per Feature-Erkennung prüfen ('contacts' in navigator && 'ContactsManager' in window) und für andere Browser eine manuelle Eingabe als Ausweichlösung anbieten.
Rückgabewert
ContactsManager-Objekt mit den Methoden select(properties, options) (liefert Promise<ContactInfo[]>) und getProperties() (liefert Promise<string[]>). In Browsern ohne Unterstützung ist die Eigenschaft undefined.Beispiele
Feature-Erkennung und unterstützte Felder abfragen
const isSupported = 'contacts' in navigator && 'ContactsManager' in window;
if (isSupported) {
const props = await navigator.contacts.getProperties();
console.log('Unterstützte Felder:', props);
} else {
console.log('Contact Picker API nicht verfügbar – manuelle Eingabe anzeigen.');
}
Telefonnummer per Klick in ein Formularfeld übernehmen
const button = document.querySelector('#pick-contact');
const telInput = document.querySelector('#tel');
button.addEventListener('click', async () => {
if (!('contacts' in navigator)) {
telInput.focus(); // Ausweichlösung: manuelle Eingabe
return;
}
try {
// select() muss direkt aus der Nutzeraktion aufgerufen werden
const [contact] = await navigator.contacts.select(['name', 'tel'], { multiple: false });
if (!contact) return; // Nutzer hat abgebrochen
telInput.value = contact.tel[0] ?? '';
console.log(`Ausgewählt: ${contact.name[0]}`);
} catch (err) {
console.error('Auswahl fehlgeschlagen:', err.name, err.message);
}
});
Mehrere Empfänger für eine Einladung auswählen
const inviteFriends = async () => {
const available = await navigator.contacts.getProperties();
// Nur Felder anfordern, die die Plattform auch kennt
const wanted = ['name', 'email'].filter((p) => available.includes(p));
const contacts = await navigator.contacts.select(wanted, { multiple: true });
const recipients = contacts
.filter((c) => c.email?.length)
.map((c) => ({ name: c.name?.[0] ?? 'Unbekannt', email: c.email[0] }));
console.table(recipients);
return recipients;
};
document.querySelector('#invite').addEventListener('click', inviteFriends);
// Wichtig · Fallstricke
- Browser-Kompatibilität: Die API ist experimentell und praktisch nur in Chrome/Edge/Samsung Internet unter Android (ab Chrome 80) verfügbar. Desktop-Chrome, Firefox und Safari unterstützen sie standardmäßig nicht (in Safari unter iOS nur über ein experimentelles Feature-Flag). Deshalb immer Feature-Erkennung und eine Ausweichlösung einbauen.
- Nutzeraktion erforderlich:
select()wirft einenSecurityError, wenn die Methode ohne vorangehende Nutzeraktion aufgerufen wird. EinInvalidStateErrorfolgt, wenn bereits ein Auswahldialog offen ist. Unbekannte Feldnamen führen zu einemTypeError. - Sicherer Kontext: Die API funktioniert nur über HTTPS (oder
localhost) und nicht in iframes. - Alle Werte sind Arrays: Jedes Feld eines
ContactInfo-Objekts (name,email,tel,address,icon) ist ein Array, das auch leer sein kann.addressliefertContactAddress-Objekte,iconliefertBlobs. - Abbruch: Schließt der Nutzer den Dialog, wird das Promise mit einem leeren Array erfüllt und nicht abgelehnt.
- Datenschutz: Fordern Sie nur die Felder an, die Sie wirklich brauchen, und behandeln Sie die erhaltenen Daten als personenbezogen (DSGVO).