captureTap(). defaultTapSources() already includes it; register it directly only when you build the source list yourself.
This is a progressive enhancement, not a replacement for the redirect source. iOS has no in-page scanning, and some Android NFC stacks detect a tag but return an empty read, so treat any failure as a cue to fall back to opening the tap link. A scan needs a live user gesture to raise the permission prompt, so run the capture from a control the user pressed, never at page load.
Example
Parameters
WebNfcTapSourceOptions
Optional configuration.
() => WebNfcWindow | undefined
Test seam that supplies the window the source reads
NDEFReader and the
permissions API from. Defaults to the page’s own window. Leave it unset in
product code.Returns
ATapSource named web-nfc that a core client registers and dispatches to.
string
required
The source identifier,
web-nfc. Pass it to captureTap({ only: [...] }) to
target this source, and match it against a captured tap’s source.number
required
WEB_NFC_TAP_SOURCE_PRIORITY, which is 0.() => boolean
required
True when the device exposes
NDEFReader. Synchronous on purpose, so
capture() runs in the same task and the gesture that gates the permission
prompt stays live.(options?) => Promise<TapResult | null>
required
Starts a scan and resolves with the captured tap. Resolves
null for a
readable tag that is not an Endstate chip, or when no reader is present.
Rejects with a WebNfcError
when a scan fails in a way the interface should present distinctly.Priority
WEB_NFC_TAP_SOURCE_PRIORITY is 0, below the redirect source’s 20. A tap already in the URL wins: on a page opened by a tap, the redirect source resolves from the URL before any scan starts. The scanner only runs when no higher-priority source captures.
Web NFC requires Android Chrome on a secure context (HTTPS or localhost).
isAvailable() returns false everywhere else, and dispatch moves on to the
next source.See also
webNfcPermissionState- gate the interface before offering a scan.WebNfcError- the typed failures a scan rejects with.

