Back to guides

Web NFC: Read and Write Tags Straight From Chrome

Chrome for Android can talk to NFC tags right from a web page — no app install. Here's how the Web NFC API actually works, its security model, and the real gaps between a browser tab and a dedicated NFC app.

Published

Quick answer

Chrome for Android can read and write NFC tags directly from a web page, using the Web NFC API's NDEFReader interface — no app install required. The catch is scope: this only runs in Chrome on Android, works only with NDEF-formatted tags, and stops well short of what a dedicated app can do. There's no Web NFC in desktop Chrome, and none in Safari on iOS at all — see how each platform's NFC stack actually differs if you're weighing iOS against Android for a project.

Step-by-step

Reading a tag with NDEFReader

You create a reader, call scan(), and listen for a reading event:

const ndef = new NDEFReader();
ndef.scan().then(() => {
  ndef.onreading = (event) => {
    for (const record of event.message.records) {
      console.log("Record type:", record.recordType);
    }
  };
});

scan() triggers Chrome's "nfc" permission prompt the first time a page calls it. It has to fire from a real tap or click — not on page load. Grant that, and every tag that comes into range fires a reading event carrying its serial number plus its NDEF records: text, URL, smart poster, MIME type, and a few other standard record types. Feature-detect with 'NDEFReader' in window first, and handle readingerror for tags that don't respond.

Writing a tag safely

Same interface for writing, but a different pattern. The documented approach is scan-then-write, not write-blind: call scan(), wait for a reading event to confirm which tag is actually present, then call write(). That's what stops you from overwriting a tag you never meant to touch.

const ndef = new NDEFReader();
await ndef.scan();
await ndef.write({ records: [{ recordType: "url", data: "https://example.com" }] });

write() takes an overwrite option to guard against clobbering a tag that already has content, and since Chrome 100, makeReadOnly() permanently locks a tag against any future write. That lock can't be undone — treat it as a one-way door.

Where the security model gets strict

Web NFC only runs in a secure context (HTTPS) and only in a top-level frame — an embedded iframe can't touch it. Every call to scan(), write(), or makeReadOnly() has to originate from a user gesture, and Chrome adds a foreground-visibility rule on top: the NFC radio is blocked whenever the screen is off or locked, and the page has to be visible at the moment you tap the tag.

That combination — HTTPS, gesture, foreground-only — rules out drive-by scanning from a background service. You always know a Web NFC page is reading or writing, because you're the one holding your phone to it.

Common problems and fixes

"NDEFReader is undefined." You're not on Chrome for Android — that's the actual platform ceiling of Web NFC, not a bug. For iOS, Safari, or desktop, you need a native app or a dedicated NFC reader/writer app instead of a web page.

Permission prompt never appears, or scan() rejects immediately. Check that the call is wired to an actual click or tap handler, not something that runs on page load — Chrome refuses gesture-less calls.

Write appears to succeed but nothing changed. Either the tag wasn't NDEF-formatted, or it left the phone's field mid-write. Web NFC only speaks NDEF, with no fallback for other formats.

Doing this on NFCore specifically

Everywhere Web NFC stops — no raw ISO-DEP commands, no peer-to-peer, no Host Card Emulation, and no way to set a tag password beyond the one-way makeReadOnly() lock — is exactly where a native app picks up. NFCore reads and writes the same NDEF tags on both iOS and Android, plus the lower-level operations a browser tab can't reach: batch writes across a stack of tags, reusable write templates, a full tag inspector for checking lock bytes and memory layout before you write anything. Outgrown what a browser tab can do? It's covered in more detail here. Grab NFCore on the App Store or Google Play when you need that extra reach.

Frequently Asked Questions

Does Web NFC work on iPhone or in Safari?

No. Web NFC (the NDEFReader API) only ships in Chrome for Android. Safari on iOS has no Web NFC support, and there's no public sign it's coming — Apple's NFC access for third parties runs through native Core NFC instead, not the browser.

Do I need to install anything to use Web NFC?

No install — it runs in Chrome for Android over a normal HTTPS page. The tradeoff is scope: you get NDEF read/write and nothing lower-level, and the page has to be open and visible when you tap the tag.

Can a website read any NFC tag with Web NFC?

Only tags formatted with NDEF, and only after you explicitly grant the "nfc" permission and tap the tag while the page is open and visible. There's no background scanning and no access to non-NDEF formats like raw MIFARE Classic sectors.

What can't Web NFC do that a native NFC app can?

It can't send raw ISO-DEP/APDU commands, can't do peer-to-peer NFC or Host Card Emulation, and has no way to set a tag password or restrict read/write access — the only protection option is makeReadOnly(), which is permanent. A native app like NFCore covers that fuller command set on both iOS and Android.

Conclusion

Web NFC is a real, no-install way to read and write NDEF tags from a web page — bounded by a strict foreground-and-permission security model and an NDEF-only scope. For anything past that — other platforms, raw tag commands, or actually protecting a tag you've written — that's where a dedicated app takes over.