Contact Picker Fullscreen Payment

Three APIs that reach into different parts of the device. Contact Picker reads from the native address book. Fullscreen expands an element to fill the screen. Payment Request collects payment details natively without your code ever seeing a card number.

June 12, 20265 min read5 / 6

Not every browser API fits neatly into a category. Some are narrowly useful. Some are things you use once and never think about again. Some are things you should know exist before you build an alternative.

These three are all of those things.

Contact Picker API

Reading contacts from the device address book is useful in exactly one scenario: you are building a social or communication app and the user wants to invite or message people they already know.

JavaScript
const contacts = await navigator.contacts.select( ['name', 'email', 'tel'], { multiple: true } ) contacts.forEach(contact => { console.log(contact.name[0]) // "Alex Kim" console.log(contact.email[0]) // "alex@example.com" console.log(contact.tel[0]) // "+1 555 0123" })

select() opens the native contact picker. The user searches, browses, and selects one or more contacts. You get back only the contacts they chose -- never the full address book.

Available properties: 'name', 'email', 'tel', 'address', 'icon'. Pass only the ones you need.

This API is deliberately narrow. You cannot iterate the contacts database. You cannot silently read contacts in the background. The user's choice is the only path to the data -- the same privacy principle behind the permission model that governs camera, microphone, and location access.

Support: Android full support. iOS is experimental -- users must enable it in Settings > Safari > Advanced > Experimental Features. Desktop browsers do not support it (no default address book on desktop).

JavaScript
if ('contacts' in navigator && 'ContactsManager' in window) { // Contact Picker is available }

Fullscreen API

Expand any DOM element to fill the screen. A video, a canvas, a div containing a game.

JavaScript
async function enterFullscreen(element) { if (element.requestFullscreen) { await element.requestFullscreen() } else if (element.webkitRequestFullscreen) { // Safari requires the webkit prefix -- one of only two APIs in this series with a prefix element.webkitRequestFullscreen() } } function exitFullscreen() { if (document.exitFullscreen) { document.exitFullscreen() } else if (document.webkitExitFullscreen) { document.webkitExitFullscreen() } }

requestFullscreen() is the only API besides Speech Synthesis that still requires a vendor prefix in Safari (webkitRequestFullscreen). For everything else in this series, the prefix era is over.

Detecting current state:

JavaScript
const currentlyFullscreen = document.fullscreenElement // null if nothing is fullscreen, otherwise the element

Responding to user-initiated exit: The user can exit fullscreen by pressing Escape or dragging from the screen edge on mobile. The fullscreenchange event fires when this happens:

JavaScript
document.addEventListener('fullscreenchange', () => { if (!document.fullscreenElement) { // User exited -- update your UI accordingly showFullscreenButton() } }) // Safari document.addEventListener('webkitfullscreenchange', () => { if (!document.webkitFullscreenElement) { showFullscreenButton() } })

Support: Green tier with the webkit caveat. Works on all browsers -- just check for the prefix on Safari.

Contact Picker, Fullscreen API, and Payment Request API: three independent OS integrations ExpandContact Picker, Fullscreen API, and Payment Request API: three independent OS integrations

Payment Request API

Collecting payment details is one of the highest-friction parts of any checkout flow. Credit card numbers, billing addresses, CVVs. Users abandon forms. They mistype card numbers.

The Payment Request API puts the browser in the middle:

JavaScript
const request = new PaymentRequest( // Payment methods [ { supportedMethods: 'https://google.com/pay' }, { supportedMethods: 'https://apple.com/apple-pay' }, { supportedMethods: 'basic-card' }, ], // Order details { total: { label: 'Total', amount: { currency: 'USD', value: '29.99' } }, displayItems: [ { label: 'FrontendMasters Annual', amount: { currency: 'USD', value: '29.99' } } ] } ) const response = await request.show() // response contains the payment token -- never the raw card number await response.complete('success')

request.show() opens the native payment UI. On Android with Google Pay configured, this is a single tap with biometric confirmation. On Safari with Apple Pay, it is a Face ID or Touch ID prompt. On other browsers, it falls back to the built-in card entry form.

You never see the credit card number. The browser collects the details, passes them directly to the payment processor's verification endpoint, and gives you back a token. Your server charges the token. The card number stays between the user and their bank.

Most developers never call this API directly. Stripe, PayPal, and Square implement it internally in their JavaScript SDKs. When you use stripe.confirmCardPayment(), the Payment Request API may be called under the hood depending on browser and configuration.

Support: Green tier across Chrome, Edge, and Safari. The specific payment methods available depend on what the user has configured on their device.

The last group of OS integration APIs covers three features that appear on the home screen icon itself: knowing whether a related native app is installed, setting a badge count on the icon, and registering shortcuts in the right-click menu. Installed Apps, Badging, and Shortcuts next.

The Essentials

  1. Contact Picker: navigator.contacts.select([props], { multiple }) -- native picker dialog, user-selected contacts only, never the full database. Android full support, iOS experimental.
  2. Fullscreen: element.requestFullscreen() + element.webkitRequestFullscreen() for Safari. document.exitFullscreen(). fullscreenchange event for user-initiated exit. Green tier with prefix caveat.
  3. document.fullscreenElement is null when nothing is fullscreen and the active element when it is.
  4. Payment Request: new PaymentRequest(methods, details)request.show() → browser native payment UI → token returned. Web developers never see card numbers. Most payment SDKs call this internally.
  5. Payment Request supports Google Pay, Apple Pay, and basic card entry as method types. Support is green tier.

Further Reading and Watching