Developer's Guide to the Web NFC API: Read, Write, and Lock Tags

By WebNfc TeamMarch 10, 2025
Developer's Guide to the Web NFC API: Read, Write, and Lock Tags

Introduction

The Web NFC API allows web applications to interact with NFC (Near Field Communication) tags. It's a powerful tool for bridging the gap between the physical and digital worlds, right from a browser. This guide provides the technical details and code snippets you need to get started.

Supported Browsers & Devices

Before you start coding, it's crucial to understand the current limitations:

  • Browser: Web NFC is primarily supported on Chrome for Android (version 89 and newer).
  • Device: It requires an Android smartphone with NFC hardware.
  • Security: The API is only available on secure contexts (HTTPS) and requires a user gesture (like a button click) to initiate any action.

How to Read an NFC Tag

To read an NFC tag, you create an instance of NDEFReader and call its scan() method. This returns a promise that resolves when a scan is initiated. The 'reading' event is fired whenever a new NDEF message is read.

async function readNfcTag() {
  if (!('NDEFReader' in window)) {
    console.log('Web NFC is not supported by this browser.');
    return;
  }
  try {
    const reader = new NDEFReader();
    await reader.scan();
    console.log('Scan started successfully.');

    reader.onreading = event => {
      console.log('NDEF message read.');
      const { serialNumber } = event;
      const { records } = event.message;
      // Process the records here
      records.forEach(record => {
        console.log(`Record type:  ${record.recordType}`);
        console.log(`MIME type:    ${record.mediaType}`);
        console.log(`Record id:      ${record.id}`);
        // ... and so on
      });
    };
  } catch (error) {
    console.error('Error starting scan:', error);
  }
}

How to Write to an NFC Tag

Writing data involves calling the write() method on an NDEFReader instance. You can write various record types, such as URLs, text, or even custom data.

async function writeNfcTag(data) {
  if (!('NDEFReader' in window)) {
    console.log('Web NFC is not supported by this browser.');
    return;
  }
  try {
    const writer = new NDEFReader();
    await writer.write({
      records: [{ recordType: 'url', data: 'https://webnfc.org' }]
    });
    console.log('Message written successfully!');
  } catch (error) {
    console.error('Error writing to tag:', error);
  }
}

How to Lock an NFC Tag (Make Read-Only)

Locking a tag prevents it from being rewritten, which is useful for permanent installations. This is an option within the write() method. Warning: This action is irreversible.

async function writeAndLockNfcTag() {
  try {
    const writer = new NDEFReader();
    await writer.write(
      { records: [{ recordType: 'text', data: 'This is a permanent message.' }] },
      { overwrite: false } // Prevent writing to a tag that already has data
    );
    // After writing, you can make the tag permanently read-only.
    await writer.makeReadOnly();
    console.log('Tag written and locked successfully!');
  } catch (error) {
    console.error('Error locking tag:', error);
  }
}

What About Cloning, and Formatting?

  • Cloning: The Web NFC API does not provide a direct 'clone' method. Cloning a tag involves reading all the NDEF records from one tag and then writing those exact records to another tag. You can implement this by combining the read and write functions shown above.
  • Formatting: Formatting a tag to remove all data is not explicitly supported by the Web NFC API. The standard way to 'clear' a tag is to simply overwrite it with a new message containing an empty NDEF record, like writer.write({ records: [{ recordType: 'empty' }] }).
Tags:
WebNFCHow-ToGuideDeveloperAPICode
✏️ Edit this page on GitHub