NDEFReader: write() method

Limited availability

This feature is not Baseline because it does not work in some of the most widely-used browsers.

Secure context: This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.

The write() method of the NDEFReader interface attempts to write an NDEF message to a tag and returns a Promise that either resolves when a message has been written to the tag or rejects if a hardware or permission error is encountered. This method triggers a permission prompt if the "nfc" permission has not been previously granted.

Syntax

js
write(message)
write(message, options)

Parameters

message

The message to be written, either a string, an ArrayBuffer, a TypedArray, a DataView, or an array of records. A record has the following members:

data Optional

Contains the data to be transmitted, a string, an ArrayBuffer, a TypedArray, a DataView, or an array of nested records

encoding Optional

A string specifying the record's encoding.

id Optional

A developer-defined identifier for the record.

lang Optional

A valid BCP 47 language tag.

mediaType Optional

A valid MIME type.

recordType

A string indicating the type of data stored in data. It must be one of the following values:

"absolute-url"

An absolute URL to the data.

"empty"

An empty NDEFRecord.

"mime"

A valid MIME type.

"smart-poster"

A smart poster as defined by the NDEF-SMARTPOSTER specification.

"text"

Text as defined by the NDEF-TEXT specification.

"unknown"

The record type is not known.

"URL"

A URL as defined by the NDEF-URI specification.

options Optional

An object with the following properties:

overwrite

A boolean value specifying whether or not existing records should be overwritten, if such exists.

signal Optional

An AbortSignal that allows the current write operation to be canceled.

Return value

A Promise that either resolves when a message has been written to the tag or rejects if a hardware or permission error is encountered.

Exceptions

This method doesn't throw exceptions; instead, it rejects the returned promise, passing a DOMException whose name is one of the following:

AbortError

The scan operation was aborted with the AbortSignal passed in the options argument.

NotAllowedError

The permission for this operation was rejected or overwrite is false and there are already records on the tag.

NotSupportedError

There is no NFC adapter compatible with Web NFC, or the available NFC adapter does not support pushing messages, or connection can not be established.

NotReadableError

The UA is not allowed to access underlying NFC adapter (e.g., due to user preference).

NetworkError

Transfer failed after it already started (e.g., the tag was removed from the reader).

Examples

Write a text string

The following example shows how to write a string to an NFC tag and process any errors that occur.

js
const ndef = new NDEFReader();
ndef
  .write("Hello World")
  .then(() => {
    console.log("Message written.");
  })
  .catch((error) => {
    console.log(`Write failed :-( try again: ${error}.`);
  });

Write a URL

The following example shows how to write a record object (described above) to an NFC tag and process any errors that occur.

js
const ndef = new NDEFReader();
try {
  await ndef.write({
    records: [{ recordType: "url", data: "http://example.com/" }],
  });
} catch {
  console.log("Write failed :-( try again.");
}

Scheduling a write with a timeout

It's sometimes useful to set a time limit on a write operation. For example, you ask the user to touch a tag, but no tag is found within a certain amount of time, then you time out.

js
const ndef = new NDEFReader();
ndef.onreading = (event) => console.log("We read a tag!");

function write(data, { timeout } = {}) {
  return new Promise((resolve, reject) => {
    const controller = new AbortController();
    controller.signal.onabort = () =>
      reject(new Error("Time is up, bailing out!"));
    setTimeout(() => controller.abort(), timeout);

    ndef.addEventListener(
      "reading",
      (event) => {
        ndef.write(data, { signal: controller.signal }).then(resolve, reject);
      },
      { once: true },
    );
  });
}

await ndef.scan();
try {
  // Let's wait for 5 seconds only.
  await write("Hello World", { timeout: 5_000 });
} catch (err) {
  console.error("Something went wrong", err);
} finally {
  console.log("We wrote to a tag!");
}

Specifications

Specification
Web NFC
# dom-ndefreader-write

Browser compatibility

desktop mobile
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
write
Experimental
Chrome – No support
Chrome
footnote No support
Edge – No support
Edge
footnote No support
Firefox – No support
Firefox
footnote No support
Opera – No support
Opera
footnote No support
Safari – No support
Safari
footnote No support
Chrome Android – Full support
Chrome Android 89 (Release date: 2021-03-02)
footnote Full support
Firefox for Android – No support
Firefox for Android
footnote No support
Opera Android – Full support
Opera Android 63 (Release date: 2021-04-16)
footnote Full support
Safari on iOS – No support
Safari on iOS
footnote No support
Samsung Internet – Full support
Samsung Internet 15 (Release date: 2021-08-13)
footnote Full support
WebView Android – Full support
WebView Android 89 (Release date: 2021-03-02)
footnote Full support
WebView on iOS – No support
WebView on iOS
footnote No support

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
No support
No support
Experimental. Expect behavior to change in the future.