deniz.in

Markets

Weather

Loading weather

· via dev.to (home feed)

Reading and writing NFC tags in the browser with the Web NFC API

A walkthrough on dev.to shows how web apps can read and write NDEF NFC tags directly in the browser using the Web NFC API, with no native app or app store install required.

Reading and writing NFC tags in the browser with the Web NFC API

What Web NFC does

Near Field Communication has traditionally been the preserve of native mobile apps: if you wanted a phone to read or program a tag, you shipped an iOS or Android application. A tutorial published on dev.to walks through the Web NFC API, which moves that capability into the browser, letting a web page read data from physical tags and write new payloads to them with no install step.

According to the author, the practical applications include digital business cards encoded as vCards, smart event passes, sharing Wi-Fi credentials and tap-based hardware interactions.

Support and feature detection

The API's reach is currently narrow. As the guide notes, native support exists in Chrome for Android from version 89 onward, and you need an Android device with an active NFC chip plus NDEF-compatible tags such as NTAG213, NTAG215 or NTAG216. Pages must also be served over HTTPS, with localhost as the development exception.

Because support is limited, the tutorial recommends detecting the API before doing anything else:

js function checkNfcSupport() { if ('NDEFReader' in window) { console.log('Web NFC is supported'); return true; } console.warn('Web NFC is not available on this browser/device'); return false; }

Reading tags

Scanning starts by constructing an NDEFReader and calling scan(). The call has to originate from a user gesture — a button press, for instance — rather than firing automatically on page load. Once active, a reading event fires when a tag comes into range, carrying both the parsed NDEF message and the tag's serial number.

The example iterates message.records and branches on record type: text records are decoded with a TextDecoder initialised with the record's own encoding, url records are decoded as plain text, and anything with a mediaType of text/vcard is treated as a contact card. A separate readingerror event covers tags that cannot be parsed, which the author suggests usually means repositioning the tag:

js async function startScanning() { const ndef = new NDEFReader(); await ndef.scan();

ndef.addEventListener('reading', ({ message, serialNumber }) => { console.log(Tag detected: ${serialNumber}); for (const record of message.records) { if (record.recordType === 'text') { const text = new TextDecoder(record.encoding).decode(record.data); console.log(text); } else if (record.recordType === 'url') { const url = new TextDecoder().decode(record.data); console.log(url); } else if (record.mediaType === 'text/vcard') { const vcard = new TextDecoder().decode(record.data); console.log(vcard); } } });

ndef.addEventListener('readingerror', () => { console.error('Could not read tag. Try holding it closer.'); }); }

Writing text, URLs and vCards

Writing goes through the same reader object. The write() method takes a records array, and the tutorial warns that a successful write replaces whatever NDEF records the tag already holds. A URL payload is the simplest case:

js async function writeUrlToTag(urlToSave) { const ndef = new NDEFReader(); await ndef.write({ records: [ { recordType: 'url', data: urlToSave } ] }); }

Contact cards take one extra step. The vCard text is assembled as CRLF-delimited lines — BEGIN:VCARD through END:VCARD, with fields such as FN, TEL, EMAIL and URL — then encoded with TextEncoder and written as a MIME record carrying mediaType 'text/vcard'.

Locking a tag read-only

NDEFReader also exposes makeReadOnly(), which permanently disables further writes to a tag. The guide is explicit that this cannot be undone, and its example asks the user for confirmation before calling the method.

Security constraints

Three rules shape how the API can be used, according to the dev.to walkthrough:

  • Both scanning and writing must be triggered by an explicit user gesture.
  • The API fails outside secure contexts, so plain HTTP will not work beyond localhost.
  • Long-running scans should be cancellable. The recommended pattern passes an AbortController signal into scan() and aborts it later — the sample times out after 15 seconds without a tap.

The author also points to NfcTool.org, a free suite of browser-based utilities built on Web NFC for inspecting tags, programming cards, locking NDEF payloads and generating vCards and QR codes.

Why it matters

Web NFC removes the biggest friction in tag-based projects: app distribution. Event check-in, inventory tagging and smart business cards become things a URL can do, which changes the economics of prototyping and small deployments. The trade-off is reach — with support confined to Chrome on Android, anything user-facing needs a fallback path. The strict gesture, HTTPS and overwrite semantics also mean developers must design carefully, particularly around write() replacing existing data and makeReadOnly() being irreversible.

  • #web-nfc
  • #nfc
  • #javascript
  • #browser-apis
  • #ndef

Related posts