A Contact Picker for the Web
What is the Contact Picker API?
Access to the user’s contacts has been a feature of native apps since (almost) the dawn of time. It’s one of the most common feature requests I hear from web developers, and is often the key reason they build a native app.
The Contact Picker API is a new, on-demand picker that allows users to select entries from their contact list and share limited details of the selected entries with a website. It allows users to share only what they want, when they want, and makes it easier for users to reach and connect with their friends and family.
For example, a web-based email client could use the Contact Picker API to select the recipient(s) of an email. A voice-over-IP app could look up which phone number to call. Or a social network could help a user discover which friends have already joined.
Want to give the Contact Picker API a try? Check out the Contact Picker API demo or view the source
Current status
Step | Status |
---|---|
1. Create explainer | Complete |
2. Create initial draft of specification | In Progress |
3. Gather feedback & iterate on design | In progress |
4. Origin trial | Starts in Chrome 77 Expected to run through Chrome 80. |
5. Launch | Not started |
Using the Contact Picker API
The Contact Picker API requires a single API call with an options parameter that specifies the types of contact information you want.
Note: Want to try the Contact Picker API? Check out the Contact Picker API demo and view the source.
Enabling via chrome://flags
To experiment with the Contact Picker API locally, without an origin
trial token, enable the #enable-experimental-web-platform-features
flag
in chrome://flags
.
Enabling support during the origin trial phase
Starting in Chrome 77, the Contact Picker API will be available as an origin trial on Chrome for Android. Origin trials allow you to try new features and give feedback on their usability, practicality, and effectiveness, both to us, and to the web standards community. For more information, see the Origin Trials Guide for Web Developers.
- Request a token for your origin.
- Add the token to your pages, there are two ways to provide this token on
any pages in your origin:
- Add an
origin-trial
<meta>
tag to the head of any page. For example, this may look something like:<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
- If you can configure your server, you can also provide the token on
pages using an
Origin-Trial
HTTP header. The resulting response header should look something like:Origin-Trial: TOKEN_GOES_HERE
- Add an
Feature detection
To check if the Contact Picker API is supported, use:
const supported = ('contacts' in navigator && 'ContactsManager' in window);
Opening the Contact Picker
The entry point to the Contact Picker API is navigator.contacts.select()
.
When called it returns a Promise and shows the Contact Picker, allowing the
user to select the contact(s) they want to share with the site. After
selecting what to share and clicking Done, the promise resolves with an
array of contacts selected by the user.
You must provide an array of properties you’d like returned as the first parameter, and optionally whether multiple contacts can be selected as a second parameter.
const props = ['name', 'email', 'tel'];
const opts = {multiple: true};
try {
const contacts = await navigator.contacts.select(props, opts);
handleResults(contacts);
} catch (ex) {
// Handle any errors here.
}
The Contacts Picker API can only be called from a secure, top-level browsing context, and like other powerful APIs, it requires a user gesture.
Handling the results
The Contact Picker API returns an array of contacts, and each contact includes an array of the requested properties. If a contact doesn’t have data for the requested property, or the user chooses to out-out of sharing a particular property, it returns an empty array.
For example, if a site requests name
, email
, and tel
, and a user
selects a single contact that has data in the name field, provides two
phone numbers, but does not have an email address, the response returned will be:
[{
"email": [],
"name": ["Queen O'Hearts"],
"tel": ["+1-206-555-1000", "+1-206-555-1111"]
}]
Note: Labels and other semantic information on contact fields are dropped.
Security and permissions
We’ve designed and implemented the Contact Picker API using the core principles defined in Controlling Access to Powerful Web Platform Features, including user control, transparency, and ergonomics.
User control
Access to the users' contacts is via the picker, it can only be called with a user gesture, on a secure, top-level browsing context. This ensures that a site can’t show the picker on page load, or randomly show the picker without any context.
There's no option to bulk-select all contacts so that users are encouraged to select only the contacts that they need to share for that particular website. Users can also control which properties are shared with the site by toggling the property button at the top of the picker.
Transparency
To clarify which contact details are being shared, the picker will always
show the contact's name and icon, plus any properties that the site has
requested. For example, if a site requests name
, email
, and tel
,
values all three properties will be shown in the picker. Alternatively,
if a site only requests tel
, the picker will show only the name, and
telephone numbers.
A long press on a contact will show all of the information that will be shared if the contact is selected (image right).
No permission persistence
Access to contacts is on-demand, and not persisted. Each time a site wants
access, it must call navigator.contacts.select()
with a user gesture,
and the user must individually choose the contact(s) they want to share
with the site.
Feedback
We want to hear about your experiences with the Contact Picker API.
Tell us about the API design
Is there something about the API that doesn’t work like you expected? Or are there missing methods or properties that you need to implement your idea?
- File a spec issue on the WICG Contact Picker API GitHub repo, or add your thoughts to an existing issue.
Problem with the implementation?
Did you find a bug with Chrome's implementation? Or is the implementation different from the spec?
- File a bug at https://new.crbug.com. Be sure to include as much
detail as you can, simple instructions for reproducing, and set
Components to
Blink>Contacts
. Glitch works great for sharing quick and easy repros.
Planning to use the API?
Planning to use the Contact Picker API? Your public support helps us to prioritize features, and shows other browser vendors how critical it is to support them.
- Share how you plan to use it on the WICG Discourse thread
- Send a Tweet to @ChromiumDev with
#contactpicker
and let us know where and how you’re using it.
Helpful Links
- Public explainer
- Contact Picker Specification
- Contact Picker API Demo & Contact Picker API demo source
- Tracking bug
- ChromeStatus.com entry
- Blink Component:
Blink>Contacts
Thanks
Big shout out and thanks to Finnur Thorarinsson and Rayan Kanso who are implementing the feature and Peter Beverloo whose code I shamelessly
stole and refactored for the demo.
PS: The 'names' in my contact picker, are characters from Alice in Wonderland.