Skip to content
Language: EN

Can a web page read an NFC tag?

Yes, in Chrome on Android, through Web NFC. The page must be served over HTTPS in a top level frame, start its first scan from a user gesture, and hold the visitor's permission. It then receives each NDEF message with the tag's serial number. No other browser ships the API, and nothing of it reaches an iPhone.

Where it works

Web NFC shipped in Chrome 89 for Android, according to the Chrome article on Web NFC. The Chrome platform status entry lists no support on desktop, on iOS or in Android's WebView, so a page shown inside an app's embedded browser does not get it either.

The other engines have said no. WebKit's published position opposes the API, citing privacy, security and device independence, and the position of Mozilla is negative. The specification is incubated by a W3C Community Group rather than published as a W3C Recommendation.

A page that reads tags therefore serves visitors on Android who use Chrome, and nobody else. That suits staff tools on phones a project controls far better than anything the public will open.

What has to happen before a scan

The page is served over HTTPS, in a top level frame rather than an iframe. The first scan() is called in response to a user gesture, such as a tap on a button, and that is when Chrome asks for the nfc permission. Once it is granted, the article's own example checks it through the Permissions API and starts scanning without waiting for a gesture.

The phone also needs NFC hardware, switched on. Feature detection does not tell you that: 'NDEFReader' in window says the browser supports Web NFC, and the promise rejects later if the hardware is missing.

The specification names the rejections. NotAllowedError means permission was refused, NotSupportedError that there is no NFC adapter, and NotReadableError that the browser is not allowed to use it, for instance because of a user setting.

What the page receives

Each tag brings a reading event with two things: the message, and serialNumber, the identifier the tag uses for anticollision, or an empty string when none is available. That identifier is not a secret, as the UID page explains.

The message holds records that the page decodes itself, by recordType: text, URL, absolute URL, MIME, smart poster, external type, empty, unknown and local types. Each record exposes its payload as a DataView, and decoding the text is left to the page.

A tag the browser cannot read as NDEF fires readingerror instead. Without a listener for it, an unsupported tag looks as if nothing happened.

What stops it

The page has to stay visible. Chrome suspends NFC operations while the page is hidden and resumes them when it comes back, and it blocks the radio when the screen is off or the phone is locked.

A tag tapped before the scan has started goes to Android, not to the page. The article says so among its tips: Android handles tags at the operating system level before Web NFC is operational, so a tag holding a link can trigger the phone's own handling of that link instead.

And scanning ends with the page. There is no background reading, so a page cannot wait in a pocket for tags the way an app registered in its manifest can.

Frequently asked questions

Does Web NFC work on iPhone?

No. Chrome's platform status entry lists no iOS support, and WebKit's published position opposes the API on privacy, security and device independence grounds.

Can a page read tags in the background?

No. Chrome suspends NFC operations while the page is hidden, and blocks the radio when the screen is off or the phone is locked.

Can Web NFC read the tag's UID?

The reading event exposes serialNumber, the identifier the tag uses for anticollision, or an empty string when none is available. It identifies a tag and proves nothing about it.

Does it work in an Android app's WebView?

No. Chrome's platform status entry lists Web NFC for Chrome on Android only, with no WebView support, so an app that needs NFC calls the native API instead.