Near Field Communication (NFC) enables wireless communication between two devices at close proximity, usually less than a few centimeters. NFC is an international standard (ISO/IEC 18092) defining an interface and protocol for simple wireless interconnection of closely coupled devices operating at 13.56 MHz. The hardware standard is deined in [[NFC-STANDARDS]].

This document defines an API to enable selected use-cases based on NFC technology.

Implementers need to be aware that this specification is considered unstable. Implementers who are not taking part in the discussions will find the specification changing out from under them in incompatible ways. Vendors interested in implementing this specification before it eventually reaches the Candidate Recommendation phase should subscribe to the repository on GitHub and take part in the discussions.

This document defines conformance criteria that apply to a single product: the UA (user agent) that implements the interfaces it contains.

Implementations that use [[!ECMAScript]] to implement the APIs defined in this document MUST implement them in a manner consistent with the [[!ECMAScript]] Bindings defined in the Web IDL specification [[!WEBIDL]], as this document uses that specification and terminology.

Terminology and conventions

The terms URL, URL scheme, URL host, URL path, URL record, parse a URL, absolute-URL string, path-absolute-URL string and basic URL parser are defined in [[!URL]].

The following terms are defined in [[!HTML]]: browsing context, top-level browsing context, global object, current settings object, Document, document base URL, Window, WindowProxy, origin, serialized origin, executing algorithms in parallel, queue a task, task source, iframe, relevant settings object, active document, environment settings object, EventHandler, focus, lose focus, unloading document cleanup steps.

A browsing context refers to the environment in which Document objects are presented to the user. A given browsing context has a single WindowProxy object, but it can have many Document objects, with their associated Window objects.

The term MIME type, Parsing a MIME type, Serializing a MIME type, valid MIME type string and JSON MIME type are defined in [[!MIMESNIFF]].

The term secure context is defined in [[!WEBAPPSEC]].

The terms visible and visibility are defined in [[!PAGE-VISIBILITY]].

The terms query a permission, request permission, "granted" and "prompt" are defined in [[!PERMISSIONS]].

The Augmented Backus-Naur Form (ABNF) notation used is specified in [[!RFC5234]].

throw, creating, DOMString, Dictionary, ArrayBuffer, BufferSource, any, not present, TypeError, DOMException, AbortError, SyntaxError, NotSupportedError, NetworkError, NotReadableError, TimeoutError, NoModificationAllowedError, and SecurityError, are defined in [[!WEBIDL]].

Promise, JSON, JSON.stringify, JSON.parse and internal slots are defined in [[!ECMASCRIPT]].

ASCII decode, ASCII encode, ASCII lowercase, ASCII hex digit, string, byte, byte sequence, set, exists, list, for each, continue, is empty, is not empty, append, contains, parse JSON from bytes and serialize JSON to bytes, are defined in [[!INFRA]].

fire an event, AbortSignal, aborted flag, and add the following abort steps are defined in [[!DOM]].

UTF-8 encoding, UTF-8 decode, UTF-8 encode, encode, and decode are defined in [[!ENCODING]].

Security related terms

The term expressed permission refers to an act by the user, e.g. via user interface or setting or host device platform features, using which the user approves the permission of a browsing context to access the given functionality.

The term ask for forgiveness refers to some form of unobtrusive notification that informs the user of an operation while it is running. UAs SHOULD provide the user with means to ignore similar future operations from the same origin and advertise this to the user.

The term prearranged trust relationship means that the UA has already established a trust relationship for a certain operation using a platform specific mechanism, so that an expressed permission from the user is not any more needed. See also this section in the Security and Privacy document.

The term obtain permission for a certain operation indicates that the UA has either obtained expressed permission, or asked for forgiveness, or ensured a prearranged trust relationship exists.

The Web NFC permission name is defined as "nfc".

NFC specific terms

NFC stands for Near Field Communications, short-range wireless technology operating at 13.56 MHz which enables communication between devices at a distance less than 10 cm. The NFC communications protocols and data exchange formats, and are based on existing radio-frequency identification (RFID) standards, including ISO/IEC 14443 and FeliCa. The NFC standards include ISO/IEC 18092[5] and those defined by the NFC Forum. See https://www.nfc-forum.org/specs/spec_list/ for a complete listing.

An NFC adapter is the software entity in the underlying platform which provides access to NFC functionality implemented in a given hardware element (NFC chip). A device may have multiple NFC adapters, for instance a built-in one, and one or more attached via USB.

An NFC tag is a passive NFC device. The NFC tag is powered by magnetic induction when an active NFC device is in proximity range. An NFC tag contains a single NDEF message.

The way of reading the message may happen through proprietary technologies, which require the reader and the tag to be of the same manufacturer. Implementations are expected to encapsulate this.

An NFC peer is an active, powered device, which can interact with other devices in order to exchange data using NFC.

An NFC device is either an NFC peer, or an NFC tag.

An NDEF message encapsulates one or more application-defined NDEF records. NDEF is an abbreviation for NFC Forum Data Exchange Format, a lightweight binary message format. NDEF messages can be stored on an NFC tag or exchanged between NFC-enabled devices.

The term NFC content is a synonym for NDEF message, which can originate either from an NFC tag or an NFC peer.

An NDEF record is a part of an NDEF message that has a single associated type information to its payload. It contains a Type Name Format (TNF) field, the payload size, the payload type, an optional identifier which is a URL, and a payload of maximum size of 2^32-1 bytes. The NFC Forum has standardized a small set of useful data types for use in NDEF records, for instance text, URL, and binary data such as media. In addition, there are record types designed for more complex interactions, such as Smart Poster, and handover records.

The TNF (Type Name Format) field of the NDEF record can take binary values denoting the following NDEF record payload types:

Value Type Name Format
0 Empty
1 NFC Forum well-known type as defined in [[!NFC-RTD]]
2 MIME type
3 Absolute-URL string
4 NFC Forum external type as defined in [[!NFC-RTD]]
5 Unknown
6 Unchanged
7 Reserved

NFC Forum well-known type includes record types text, URI, Smart Poster (containing a URL or other data, and possible actions).

A Web NFC message consists of a sequence of NDEF records, one of which is a Web NFC record.

The Web NFC message origin is a serialized origin with "https" scheme, stored in the Web NFC record. For NFC content that is not a Web NFC message, it is null.

The Web NFC Id is an absolute-URL string, specifically the Web NFC message origin optionally followed by a path-absolute-URL string, stored in the Web NFC Record. This enables matching Web NFC content with URL patterns specified by NFCReaders.

A Web NFC record is an NDEF record of external type type, specific to Web NFC. It indicates that the containing NDEF message is targeted for browsing contexts using this API and contains information useful for handling the NDEF message with the algorithms defined in this specification. The format of a Web NFC record is as follows:

The term Web NFC content denotes all Web NFC messages contained within an NDEF message, identified by the Web NFC Id within the NDEF message. This version of the specification supports one Web NFC message per NDEF message.

As part of the NDEF record, an NDEF Id field may be present for application specific usages. According to the [[NFC-STANDARDS]] it contains a URL with the maximum length of 256 bytes. This URL is used for identifying the NDEF record payload in an application specific way. This version of the specification does not use NDEF Id for NDEF record level payload identification, since NDEF message level identification is used.

An NFC handover defines NFC Forum Well Known Types and the corresponding message structure that allows negotiation and activation of an alternative communication carrier, such as Bluetooth or WiFi. The negotiated communication carrier would then be used (separately) to perform certain activities between the two devices, such as sending photos to the other device, printing to a Bluetooth printer or streaming video to a television set.

Introduction

In general, there are following groups of user scenarios for NFC:

NFC works using magnetic induction, meaning that the reader will emit a small electric charge which then creates a magnetic field. This field powers the passive device which turns it into electrical impulses to communicate data. Thus, when the devices are within range, a read is always performed (see NFC Analog Specification and NFC Digital Protocol, NFC Forum, 2006). The peer-to-peer connection works in a similar way, as the device periodically switches into a so-called initiator mode in order to scan for targets, then later to fall back into target mode. If a target is found, the data is read the same way as for tags.

As NFC is based on existing RFID standards, many NFC chipsets support reading RFID tags, but many of these are only supported by single vendors and not part of the NFC standards. Though certain devices support reading and writing to these, it is not a goal of this document to support proprietary tags or support interoperability with legacy systems.

The NFC Forum has mandated the support of five different tag types to be operable with NFC devices. The same is required on operating systems such as Android.

  1. NFC Forum Type 1: This tag is based on the ISO/IEC 14443-3A (also known as NFC-A, as defined in ISO/IEC 14443-3:2011, Part 3: Initialization and anticollision). The tags are rewritable and can be configured to become read-only. Memory size can be between 96 bytes and 2 Kbytes. Communication speed is 106 kbit/sec.
  2. NFC Forum Type 2: This tag is also based on the ISO/IEC 14443-3A (NFC-A). The tags are rewritable and can be configured to become read-only. Memory size can be between 48 bytes and 2 Kbytes. Communication speed is 106 kbit/sec. In contrast to Type 1, Type 2 has anti-collision protection for dealing with multiple tags within the NFC field.
  3. NFC Forum Type 3: This tag is based on the Japanese Industrial Standard (JIS) X 6319-4, commonly known as FeliCa. The tags are preconfigured to be either rewritable or read-only. Memory availability is variable, theoretical memory limit is 1MByte per service. Communication speed is 106 kbit/sec. Like Type 2, it supports anti-collision protection.
  4. NFC Forum Type 4 (November 2010): This tag is based on the ISO/IEC 14443 like Type 1 and 2, but it supports either NFC-A or NFC-B for communication. On top of that the tag may support the Data Exchange Protocol (aka ISO-DEP) defined in ISO/IEC 14443 (ISO/IEC 14443-4:2008 Part 4: Transmission protocol). Like Type 3, the tags are preconfigured to be either rewritable or read-only. Variable memory, up to 32 KB per service. Supports three different communication speeds 106 or 212 or 424 Kbits/s.
  5. NFC Forum Type 5: This tag is based on the NFC-V RF technology which is based on ISO/IEC 15693 and allows reading and writing an NDEF message on a ISO/IEC 15693 RF tag that is accessible by long range RFID readers as well. The NFC communication is limited to short distance and may use the Active Communication Mode of ISO/IEC 18092 where the sending peer generates the field which balances power consumption and improves link stability.

In addition to data types standardized for NDEF records by the NFC Forum, many commercial products such as bus cards, door openers etc use different card specific data and protocol extensions which require specific NFC chips (same vendor of card and reader) in order to function.

Card emulation mode capabilities also depend on the NFC chip in the device. For payments, a Secure Element is often needed.

This document does not aim supporting all possible use cases of NFC technology, but only a few use cases which are considered relevant to be used by web pages in browsers, using the browser security model.

Examples

This section shows how developers can make use of the various features of this specification.

Use Cases

A few Web NFC user scenarios are described in the Use Cases document. These user scenarios can be grouped by criteria based on security, privacy and feature categories, resulting in generic flows as follows.

Reading an NFC tag

  1. Reading an NFC tag containing a Web NFC message, when a web page using the Web NFC API is open and in focus. For instance, a web page instructs the user to tap an NFC tag, and then receives information from the tag.
  2. Reading an NFC tag containing other than Web NFC message, when a web page using the Web NFC API is open and in focus.
  3. Reading an NFC tag when no web site using the Web NFC API is open or in focus.

    This use case is not supported in this version of the specification, and it has low priority for future versions as well.

Writing to an NFC tag

The user opens a web page which can write an NFC tag. The write operations may be one of the following:

  1. Writing to an empty NFC tag.
  2. Writing to an NFC tag which already contains a Web NFC message with a different Web NFC message origin (i.e. overwriting a web-specific tag).
  3. Writing to an NFC tag which already contains a Web NFC message with the same Web NFC message origin (i.e. updating own tag).
  4. Writing to other, writable NFC tags (i.e. overwriting a generic tag).

Note that an NFC write operation to an NFC tag always involves also a read operation.

Pushing data to an NFC peer device

In general, pushing data to another Web NFC capable device requires that on the initiating device the user would first have to navigate to a web site. The user would then touch the device against another Web NFC equipped device, and data transfer would occur.

On the receiving device the UA will dispatch the content to an application registered and eligible to handle the content, and if that application is a browser which has a web page open and in focus with active NFCReader, then the content is delivered to the page through the NFCReadingEvent.

Handover to another wireless connection type

NFC supports handover protocols to Bluetooth or WiFi connectivity for the purpose of larger volume data transfer. The user touches another NFC capable device, and as a result configuration data is sent for a new Bluetooth or WiFi connection, which is then established between the devices.

This use case is not supported in this version of the specification.

Payment scenarios

Payment scenarios with Web NFC generally do not refer to supporting the payment process itself, but associating the payment status with a web page in order to have secondary actions. For instance, the user buys goods in a store, and payments options include contactless payment using NFC technology. In general, touching the device to the point of sales terminal receiver area will result in a transaction between the secure element from the device and the point of sales terminal. With the Web NFC API, if the user navigates to a web site before paying, there may be interaction with that site regarding the payment, e.g. the user could get points and discounts, or get delivered application or service specific data (e.g. tickets, keys, etc) to the device.

This use case is not supported in this version of the specification.

Support for multiple NFC adapters

Users may attach one or more external NFC adapters to their devices, in addition to a built-in adapter. Users may use either NFC adapter.

Features

High level features for the Web NFC specification include the following:

  1. Support devices with single or multiple NFC adapters. If there are multiple adapters present when invoking an NFC function then the UA operates all NFC adapters in parallel.
  2. Support communication with active (powered devices such as readers, phones) and passive (smart cards, tags, etc) devices.
  3. Allow users to act on (e.g. read, write or transceive) discovered NFC devices (passive and active), as well as access the payload which were read in the process as Web NFC messages.
  4. Allow users to write a payload via NDEF records to compatible devices, such as writeable tags, when they come in range, as Web NFC messages.
  5. [future] Allow manual connection for various technologies such as NFC-A and NFC-F depending on the secondary device.
  6. [future] Allow NFC handover to Bluetooth or WiFi.
  7. [future] Allow card emulation with secure element or host card emulation.

This specification makes a few simplifications in what use cases and data types the Web NFC API can handle:

Security and Privacy

The trust model, attacker model, threat model and possible mitigation proposals for the Web NFC API are presented in the Security and Privacy document. This section presents the chosen security and privacy model through normative requirements to implementations.

Chain of trust

Web pages using the Web NFC API are not trusted. This means that the user needs to be aware of exactly what a web page is intending to do with NFC at any given moment. Implementations need to make sure that when the user authorizes a method of this API, then only that action is run, without side effects, and exactly in the context and the number of times the user allows the execution of NFC related operations, according to the algorithmic steps detailed in this specification.

The integrity of NFC content SHOULD NOT be trusted when used for implementing security policies, for instance the authenticity of origins saved in the Web NFC Id, unless a prearranged trust relationship exists.

Threats

The main threats are summarized in the Security and Privacy document.

In this specification the following threats are handled with the highest priority:

Permissions and user prompts

This specification attempts to minimize user prompting and uses implicit security policies to address the threats. However, this specification does not describe, nor does it mandate specific user prompting policies. The term obtain permission is used for acquiring trust for a given operation.

The Permissions API [[!PERMISSIONS]] is suggested to be used by UAs for implementing NFC related [[permissions]] in order to minimize the need for user prompting.

All expressed permissions that are preserved beyond the current browsing session MUST be revocable.

Security policies

This section summarizes the security policies which are specified as normative requirements in the respective algorithms of this specification:

Data Representation

The NDEFMessage dictionary

The content of any Web NFC message is exposed by the NDEFMessage dictionary:

      dictionary NDEFMessage {
        DOMString? serialNumber;
        sequence<NDEFRecord> records;
        USVString url;
      };
    

The NDEFMessage.serialNumber property represents a serial number used for anti-collision and identification, or null in case none is available.

Though most tags will have a stable unique identifier (UID), not all have one and some tags even create a random number on each read. The serial number usually consists of 4 or 7 numbers, separated by :.

The NDEFMessage.url property represents the Web NFC Id of a received Web NFC message. When used in the NFCWriter.push() method, it represents a URL path used for constructing the Web NFC Id of the pushed Web NFC content.

The NDEFMessage.records property represents a list of NDEF messages defining the Web NFC message.

The NDEFRecord dictionary

The content of any NDEF record is exposed by the NDEFRecord dictionary:

      typedef (DOMString or unrestricted double or ArrayBuffer or Dictionary) NDEFRecordData;

      dictionary NDEFRecord {
        NDEFRecordType recordType;
        USVString mediaType;
        NDEFRecordData data;
      };
    

The NDEFRecordData is a union type representing data types allowed for NDEFRecord.data property.

The NDEFRecord.mediaType property represents the MIME type of the NDEF record payload.

The NDEFRecord.data property represents the payload data of the NDEF record with an appropriate [[!ECMAScript]] type, which depends on the MIME type.

The NDEFRecord.recordType property represents the NDEF record types. The mapping from data types of an NDEFRecord to and from NDEF record types is presented in the algorithmic steps which handle the data and described in the Receiving and parsing content and Writing or pushing content sections.

The NDEFRecordType enum

This enum defines the set of known types for a NDEFRecord. The data mapping section describes how NDEFRecordType is mapped to NDEF record types.

        enum NDEFRecordType {
          "empty",
          "text",
          "url",
          "json",
          "opaque"
        };
      
empty
The enum value representing empty NDEFRecord.
text
The enum value representing NDEFRecord of a text type.
url
The enum value representing NDEFRecord of a url type.
json
The enum value representing NDEFRecord of a json type.
opaque
The enum value representing NDEFRecord of an opaque type.

Data mapping

The mapping from data types of an NDEFRecord to NDEF record types, as used in the Writing or pushing content section is as follows:

NDEFRecord recordType NDEFRecord mediaType NDEFRecord data NDEF record type
"empty" not used not used Empty (TNF=0) record
"text" not used DOMString NFC Forum well-known type (TNF=1) record with type Text
"url" not used DOMString NFC Forum well-known type (TNF=1) record with type URI
"json" JSON MIME type null or DOMString or Number or Dictionary MIME type (TNF=2) record with MIME type specified in the type attribute.
"opaque" MIME type ArrayBuffer MIME type (TNF=2) record
"" (empty) ArrayBuffer or typed array NFC Forum external type (TNF=4) record

The mapping from NDEF record types to NDEFRecord, as used for incoming NDEF messages described in the Receiving and parsing content section, is as follows:

NDEF record type NDEFRecord recordType NDEFRecord mediaType NDEFRecord data
Empty (TNF=0) record "empty" "" null
NFC Forum well-known type (TNF=1) record with type Text "text" "text/plain" DOMString
NFC Forum well-known type (TNF=1) record with type URI "url" "text/plain" DOMString
NFC Forum well-known type (TNF=1) record with type Smart Poster "url" "text/plain" DOMString
Absolute-URL string (TNF=3) record "url" "text/plain" DOMString
MIME type (TNF=2) record with JSON MIME type "json" The MIME type used in the NDEF record null or DOMString or Number or Dictionary
MIME type (TNF=2) record "opaque" The MIME type used in the NDEF record ArrayBuffer
NFC Forum external type type (TNF=4) record with type other than urn:nfc:ext:w3.org:webnfc* "opaque" "application/octet-stream" ArrayBuffer
Any other NDEF record type "opaque" "application/octet-stream" ArrayBuffer

The Web NFC records MUST NOT be exposed to client browsing contexts.

The NFCReader and NFCWriter objects

The objects provide a way for the browsing context to use NFC functionality. They allow for pushing Web NFC messages to NFC tags or NFC peers within range, and to act on incoming Web NFC messages either from an NFC tag or an NFC peer.
    typedef (DOMString or ArrayBuffer or NDEFMessage) NDEFMessageSource;

    [Constructor(), SecureContext, Exposed=Window]
    interface NFCWriter {
      Promise<void> push(NDEFMessageSource message, optional NFCPushOptions options);
    };

    [Constructor(optional NFCReaderOptions options), SecureContext, Exposed=Window]
    interface NFCReader : EventTarget {
      attribute EventHandler onreading;
      attribute EventHandler onerror;

      void start();
      void stop();
    };

    [Constructor(DOMString type, NFCReadingEventInit readingEventInitDict), SecureContext, Exposed=Window]
    interface NFCReadingEvent : Event {
      readonly attribute NDEFMessage message;
    };

    dictionary NFCReadingEventInit : EventInit {
      required NDEFMessage message;
    };

    [Constructor(DOMString type, NFCErrorEventInit errorEventInitDict), SecureContext, Exposed=Window]
    interface NFCErrorEvent : Event {
      readonly attribute DOMException error;
    };

    dictionary NFCErrorEventInit : EventInit {
      required DOMException error;
    };

  

The NDEFMessageSource is a union type representing argument types accepted by the push() method.

The NFCReadingEvent is the event being dispatched on new NFC readings, with the NDEFMessage object as the NFCReadingEvent.message attribute. NFCReadingEventInit is used in order to initialize a new event with a the NDEFMessage data via the NFCReadingEventInit.message member.

The NFCErrorEvent is the event being dispatched on errors, with the DOMException object as the NFCErrorEvent.error attribute. NFCErrorEventInit is used in order to initialize a new event with a DOMException data via the NFCErrorEventInit.error member.

The NFCWriter is an object used for writing data to NFC devices such as tags.

The NFCReader is an object used for reading data when a device, such as a tag, is within the magnetic induction field.

The NFCReader.onreading is an EventHandler which is called to notify that new reading is available.

The NFCReader.onerror is an EventHandler which is called to notify that an error happened.

NFC state associated with the settings object

The relevant settings object of the active document of a browsing context which supports NFC has an associated NFC state record with the following internal slots:

Internal Slot Description (non-normative)
[[\Suspended]] A boolean flag indicating whether NFC functionality is suspended or not, initially false.
[[\ActivatedReaderList]] A set of NFCReader instances initially set to the empty set.

Internal slots are used only as a notation in this specification, and implementations do not necessarily have to map them to explicit internal properties.

Handling NFC adapters

Implementations MAY use multiple NFC adapters according to the algorithmic steps described in this specification.

Handling Window visibility and focus

Each Window object where NFC is exposed has a separate NFC instance. The visibility and focus state of the Window object determines the suspended state of the associated NFC instance.

The term suspended in this specification refers to NFC operations being suspended, i.e. no NFC content is pushed by NFCWriters, and no received NFC content is presented to any NFCReader while suspended. However, platform level timers for the NFCWriter.push() method continue running, and if they expire, the event should be recorded and handled when execution next resumes, i.e. when the focus event is fired on the Window object.

To suspend NFC, set the [[\Suspended]] internal slot of the current settings object's associated NFC state to true.

To resume NFC, set the [[\Suspended]] internal slot of the current settings object's associated NFC state to false.

NFC is suspended if the [[\Suspended]] internal slot of the current settings object's associated NFC state is true.

The activated reader objects is the value of the [[\ActivatedReaderList]] internal slot of the current settings object's associated NFC state.

When the Window object associated with the Document using the Web NFC API becomes visible and in focus, resume NFC.

When the Window object associated with the Document using the Web NFC API loses focus, suspend NFC.

Releasing NFC

To release NFC on an environment settings object settings, perform the following steps:

  1. Suspend NFC.
  2. For each pending NFCWriter.push() associated with settings:
    1. Stop the instance's timer if it is active.
    2. If the instance has already initiated NFC data transfer, continue.
    3. Reject p with an "AbortError" DOMException and abort these steps.
  3. Stop the dispatch NFC content steps.
  4. Clear the activated reader objects.
  5. Release the NFC resources associated with nfc on the underlying platform.

The UA must release NFC given the document's relevant settings object as additional unloading document cleanup steps.

The NDEFCompatibility enum

To describe what NDEF compatible devices are accepted as vendor specific tags exist that support NDEF but which are not universally supported by all NFC readers, or by the NFC standard.

          enum NDEFCompatibility {
            "nfc-forum",
            "vendor",
            "any"
          };
        

nfc-forum
The enum value representing all active and passive NFC devices, supported by the NFC standard.
vendor
The enum value representing vendor specific NFC tags (passive device) that require specific reader chips.
any
The enum value representing all NDEF compatible devices that the reader chip can read.

The NFCPushOptions dictionary

      dictionary NFCPushOptions {
        NFCPushTarget target = "any";
        unrestricted double timeout = Infinity;
        boolean ignoreRead = true;
        AbortSignal? signal;
        NDEFCompatibility compatibility = "nfc-forum";
      };
    

The NFCPushOptions.target property denotes the intended target for the pending push() operation.

The NFCPushOptions.timeout property denotes the timeout for the pending push() operation expressed in milliseconds. The default value is implementation-dependent. The value Infinity means there is no timeout, i.e. no timer is started. After the timeout expires, the message set for pushing is cleared, an error is returned, and a new Web NFC message can be set for pushing.

When the value of the NFCPushOptions.ignoreRead property is true, the push algorithm will skip invoking the receiving and parsing steps for an NFC tag.

The NFCPushOptions.signal property allows to abort the push() operation.

The NFCPushOptions.compatibility property denotes the accepted kind of NFC devices.

The NFCPushTarget enum

This enum defines the set of intended target values for the push() operation.

      enum NFCPushTarget {
        "tag",
        "peer",
        "any"
      };
    
tag
The enum value representing the intended target for the push() operation to be a NFC tag.
peer
The enum value representing the intended target for the push() operation to be a NFC peer.
any
The enum value representing the intended target for the push() operation to be a NFC tag or a NFC peer.

The NFCReaderOptions dictionary

To describe which messages an application is interested in, the NFCReaderOptions dictionary is used:

        dictionary NFCReaderOptions {
          USVString url = "";
          NDEFRecordType recordType;
          USVString mediaType = "";
          NDEFCompatibility compatibility = "nfc-forum";
        };
      

The NFCReaderOptions.url property denotes the URL pattern which is used for matching the Web NFC Id of Web NFC messages which are being read. The default value "" means that no matching happens.

The NFCReaderOptions.recordType property denotes the enum value which is used for matching the recordType property of each NDEFRecord object in a Web NFC message. If the dictionary member is not present, then it will be ignored by the NFC listen algorithm.

The NFCReaderOptions.mediaType property denotes the match pattern which is used for matching the mediaType property of each NDEFRecord object in a Web NFC message. The default value "" means that no matching happens.

The NFCReaderOptions.compatibility property denotes the accepted kind of NFC devices.

        const options = {
          url: "https://www.w3.org/*",  // any path from the domain is accepted
          recordType: "json",
          mediaType: "application/*+json"  // any JSON-based MIME type
        }
      
        const options = {
          url: "https://w3.org/info/restaurant/daily-menu/",
          recordType: "opaque",
          mediaType: "application/octet-stream"
        }
      

Constructing an NFCReader object

  1. Let reader be a new NFCReader object.
  2. Let options be first argument to constructor.
  3. For each keyvalue of options:
    • If key equals "url", set reader.[[\Url]] to value.
    • Otherwise, if key equals "recordType", set reader.[[\RecordType]] to value.
    • Otherwise, if key equals "mediaType", set reader.[[\MediaType]] to value.
    • Otherwise, if key equals "compatibility", set reader.[[\Compatibility]] to value.
  4. Return reader.

Writing or pushing content

This section describes how to write an NDEF message to an NFC tag or how to push it to an NFC peer device when it is next time in proximity range before a timer expires. At any time there is at maximum of two Web NFC messages that can be set for pushing for an origin: one targeted to NFC tags and one to NFC peers, until the current message is sent, a timeout happens, or the push is aborted.

The push() method

The NFCWriter.push method, when invoked, MUST run the push a message algorithm:

  1. Let p be a new Promise object.
  2. Let message be the first argument.
  3. Let options be the second argument.
  4. Let signal be the options’ dictionary member of the same name if present, or null otherwise.
  5. If there is no underlying NFC Adapter, or if a connection cannot be established, then reject p with a "NotReadableError" DOMException and return p.
  6. If pushing data is not supported by the underlying NFC Adapter, then reject p with a "NotSupportedError" DOMExceptionand return p.
  7. If signal’s aborted flag is set, then reject p with an "AbortError" DOMException and return p.
  8. If signal is not null, then add the following abort steps to signal:
    1. Stop the instance's timer if it is active.
    2. If the instance has already initiated NFC data transfer, reject p with "NoModificationAllowedError" DOMException and abort these steps.
    3. Reject p with an "AbortError" DOMException and abort these steps.
  9. Run the following steps in parallel:
    1. An implementation MAY reject p with "NotSupportedError" DOMException and abort these steps.
      The UA might terminate message push at this point. The reasons for terminations are implementation details. For example, the user could have has set a preference to allow a given origin only to read, write, or push data to peers. Also, the implementation might be unable to support the operation requested.
    2. Let target be options's target.
    3. Let timeout be options's timeout.
    4. Let compatibility be options's compatibility.
    5. If the message parameter is not of type defined by the NDEFMessageSource union, reject p with TypeError, and abort these steps.
    6. If the message parameter is of NDEFMessage type, and message's records is empty, reject p with TypeError and abort these steps.
    7. If timeout value is NaN or negative, reject p with TypeError and abort these steps.
    8. If timeout value is not supported by the UA, reject p with "NotSupportedError" DOMException and abort these steps.
    9. Let output be the notation for the NDEF message to be created by UA, as the result of passing message to create Web NFC message. If this throws an exception, reject p with that exception and abort these steps.
    10. If target is "any", run the following steps twice, once with slot set to the value "tag", and once set to the value "peer"; otherwise run the following step once, with slot set to the value of target.
      • If there are any existing instance of this algorithm running whose target is equal to slot, abort that instance of this algorithm by rejecting its p with "AbortError" DOMException.

        In other words, the current invocation of push() rejects and replaces existing running invocations handling the same slot. At any given moment there may be maximum two instances of this algorithm running: one targeting NFC tags, and another targeting NFC peers.

        Implementations are expected to clean up state on aborting these steps, e.g. stop the related timer, clear the related push message, as well as release any resources bound to NFC functionality, so that new invocations of this algorithm do not depend on previous invocations.

      • Associate output with slot.
    11. If timeout value is not equal to Infinity, start a timer timer with the timeout value set to timeout.
    12. Wait until one of the following events happens:
      • Promise p is rejected for a reason such as being aborted by the user. In that case, abort these steps.
      • If timer expires, reject p with "TimeoutError" DOMException and abort these steps.
      • If an NFC device device comes within communication range, verify the following conditions:
        • if device is not officially supported by the NFC Forum, compatibility is "vendor" or "any".
        • if device is an NFC tag, target is "tag" or "any".
        • if device is an NFC peer, target is "peer" or "any".
        • NFC is not suspended.
        In case of success, run the following sub-steps:
        1. Stop timer if active.
        2. If device is an NFC tag,
        3. Initiate data transfer to device using output as buffer, using the NFC adapter in communication range with (connected to) device.
        4. If the transfer fails, reject p with "NetworkError" DOMException and abort these steps.

          Multiple adapters should be used sequentially by users. There is very small likelihood that a simultaneous tap will happen on two or multiple different and connected NFC adapters. If it happens, the user will likely need to repeat the taps until success, preferably one device at a time. The error here gives an indication that the operation needs to be repeated. Otherwise the user may think the operation succeeded on all connected NFC adapters.

        5. When the transfer has completed, clear output associated with target, resolve p.

    If NFC is suspended, continue waiting until timer expires (if set), or promise is aborted by the user, or until an NFC device comes within communication range.

Obtaining push permission

To obtain push permission, run these steps:

  1. If there is a prearranged trust relationship, return true.
  2. Run the query a permission steps for the Web NFC permission name until completion.
  3. Return false.

Creating Web NFC message

To create Web NFC message given a message run these steps:

  1. Let output be the notation for the NDEF message to be created by the UA as a result of these steps.
  2. For each NDEFRecord record in the list message's records, run the following steps, or make sure that the underlying platform provides equivalent values to ndef:
    1. If record's recordType is undefined, then:
      1. If the type of record's data is an ArrayBuffer, then set record's recordType to "opaque".
      2. Otherwise, if the type of record's data is an Object, then set record's recordType to "json".
      3. Otherwise, if the type of record's data is UnrestrictedDouble or String, then set record's recordType to "text".
      4. Otherwise reject promise with TypeError and abort these steps.
    2. If record's recordType is "empty", then Let ndef be the result of passing record to map empty record to NDEF. If this throws an exception, reject promise with that exception and abort these steps.
    3. Otherwise, if record's recordType is "text", then let ndef be the result of passing record to map text to NDEF. If this throws an exception, reject promise with that exception and abort these steps.
    4. Otherwise, if record"url", then let ndef the be result of passing record to map a URL to NDEF. If this throws an exception, reject promise with that exception and abort these steps.
    5. Otherwise, if record's recordType is "json", then let ndef the be result of passing record to map a JSON object to NDEF. If this throws an exception, reject promise with that exception and abort these steps.
    6. Otherwise, if record's recordType is "opaque", then let ndef the be result of passing record to map binary data to NDEF. If this throws an exception, reject promise with that exception and abort these steps.
    7. Add ndef to output.
  3. Let webnfc be the result of invoking create a Web NFC record given message's url. If this throws an exception, reject promise with that exception and abort these steps.
  4. Add webnfc to output.

    Implementations may choose the location of the Web NFC record within the NDEF message.

Mapping empty record to NDEF

To map empty record to NDEF given a record, run these steps:

  1. Let ndef be the notation for the NDEF record to be created by the UA.
  2. Set the ndef's TNF field to 0 (empty).
  3. Set ndef's TYPE_LENGTH, ID_LENGTH and PAYLOAD_LENGTH fields to 0, and omit the associated fields from the NDEF record: TYPE, ID, and PAYLOAD.
  4. Return ndef.

Mapping string to NDEF

To map text to NDEF given a record, run these steps:

This is useful when clients specifically want to write an NDEF Well Known Type Text record. Other options would be to use the value "opaque" with an explicit MIME type text type, which allows for better differentiation, e.g. when using "text/xml", or "text/vcard".

  1. If the type of a record's data is not a String or a UnrestrictedDouble, throw a TypeError and abort these steps.
  2. Let MIME type be the MIME type record returned by running parsing a MIME type on record's mediaType.
  3. If MIME type is failure, set record's mediaType to "text/plain".
  4. If MIME type's type is not "text", then throw a "SyntaxError" DOMException and abort these steps.
  5. Let language be "en". If MIME type's parameters["lang"] exists, then set language to MIME type's parameters["lang"].

    Note that lang= is not standard parameter to MIME types, but it is used in this specification in order to maintain compatibility with [[NFC-STANDARDS]].

  6. Let ndef be the notation for the NDEF record to be created by the UA.
  7. Set the ndef's TNF field to 1 (well-known type).
  8. Set the ndef's TYPE field to "T" (value 0x54 following NFC binary encoding).
  9. Set the ndef's PAYLOAD field to record's data encoded according to the [[!NFC-STANDARDS]], NFC Forum Text Record Type Definition specification:
    1. To set the first byte of the byte sequence of ndef's PAYLOAD field, perform the following steps:
      1. If MIME type's parameters["charset"] exists, set charset to be the result of running ASCII lowercase on the value.
      2. If charset is not equal to "utf-8", throw a TypeError.
      3. Set bit 7 (most significant bit) to the value 0 (meaning UTF-8 encoding).
      4. Set bit 6 to the value 0 (reserved).
      5. Let offset be the length of the language string.
      6. Set bit 5 to bit 0 to offset.
    2. Set position 1 to offset + 1, inclusive, of the byte sequence of ndef's PAYLOAD field to the result of running ASCII encode on language.
    3. Set position from offset + 1 to end, of the byte sequence of ndef's PAYLOAD field to the result of running UTF-8 encode on record's data.
  10. Return ndef.

Mapping URL to NDEF

To map a URL to NDEF given a record, run these steps:

  1. If record's data is not a string, throw a TypeError and abort these steps.
  2. Let urlRecord be the result of parsing record's data.
  3. If urlRecord is failure, throw a "SyntaxError" DOMException and abort these steps.
  4. Let ndef be the notation for the NDEF record to be created by the UA.
  5. Set the ndef's TNF field to 1 (well-known type).
  6. Set the ndef's TYPE field to "U" (0x55 following NFC binary encoding).
  7. Match the URI prefixes as defined in [[!NFC-STANDARDS]] URI Record Type Definition specification, Section 3.2.2, against the urlRecord.
  8. Let prefix be the matched prefix or else the empty string.
  9. Let prefix code be the corresponding prefix number, or else 0.
  10. Let shortened url be urlRecord with prefix removed from the start of the string.
  11. Set the first byte of ndef's PAYLOAD field to the prefix code.
  12. Set position 1 to end, of the byte sequence of ndef's PAYLOAD field to the result of running UTF-8 encode on shortened url.
  13. Return ndef.

Mapping JSON to NDEF

To map a JSON object to NDEF given a record, run these steps:

  1. If the type of a record's data is not an Object, throw a TypeError and abort these steps.
  2. Let MIME type be the MIME type record returned by running parsing a MIME type on record's mediaType.
  3. If MIME type is failure, set record's mediaType to "application/json".
  4. If MIME type is not a JSON MIME type, then throw a "SyntaxError" DOMException and abort these steps.
  5. Let data be the result of executing serialize JSON to bytes on record's data.
  6. Let ndef be the notation for the NDEF record to be created by the UA.
  7. Set the ndef's TNF field to 2 (MIME type).
  8. Set the ndef's TYPE field to the result of serializing a MIME type with MIME type as the input.
  9. Set the ndef's PAYLOAD field to data according to the [[!NFC-STANDARDS]], i.e. as an opaque byte sequence.
  10. Return ndef.

Mapping binary data to NDEF

To map binary data to NDEF given a record, run these steps:

  1. If the type of a record's data is not an ArrayBuffer, throw a TypeError and abort these steps.
  2. Let MIME type be the MIME type record returned by running parsing a MIME type on record's mediaType.
  3. If MIME type is failure, set record's mediaType to "application/octet-stream".
  4. Let ndef be the notation for the NDEF record to be created by the UA.
  5. Set the ndef's TNF field to 2 (MIME type).
  6. Set the ndef's TYPE field to the result of serializing a MIME type with MIME type as the input.
  7. Set the ndef's PAYLOAD field to record's data according to the [[!NFC-STANDARDS]], i.e. as an opaque byte sequence
  8. Return ndef.

Creating a Web NFC record

To create a Web NFC record given URL path urlPath, run these steps:

  1. Let ndef be the notation for the NDEF record to be created by the UA.
  2. Set ndef's TNF to 4 (external type).
  3. Set ndef's TYPE to "urn:nfc:ext:w3.org:webnfc".
  4. Set ndef's PAYLOAD to the result of invoking create a Web NFC Id given urlPath. If this throws an exception, re-throw it.
  5. Return ndef.

Creating a Web NFC Id

To create a Web NFC Id given URL path urlPath, run these steps:

  1. Let id be the serialized origin of the current settings object.
  2. Append urlPath to id.
  3. Let urlRecord be the result of parsing id.
  4. If urlRecord is failure, throw a "SyntaxError" DOMException and abort these steps.
  5. Return id.

Listening for content

In order to receive NFC content, the client needs to attach an event listener for the "reading" event on an NFCReader instance and then activate it by calling NFCReader.start().

Each NFCReader can filter the NFC content based on data type, and the URL path of the browsing context which has been saved to the Web NFC record of the NFC content.

If you filter by URL path, that means it will be matched against the Web NFC record, thus the presence of such is required. If you don't filter by URL path, then all NFC devices are accepted.

The latter is matched against the URL patterns associated with the activated reader objects.

Match patterns

A match pattern is defined by the following ABNF:

          match-pattern       = top-level-type-name "/" [ tree "." ] subtype-name [ "+" suffix ] [ ";" parameters ]
          top-level-type-name = "*" / < VCHAR except "/" and "*" >
          subtype-name        = "*" / < VCHAR except "+" >
        
A match pattern is a glob used for matching MIME types, for instance the pattern 'application/*+json' matches 'application/calendar+json', but does not match 'application/json'. The pattern '*/*json', on the other hand, matches both.

URL patterns

A URL pattern is a URL record that can be used to match the Web NFC Id of a Web NFC message. A valid URL pattern is a valid URL record whose scheme component is equal to "https".

A URL pattern's scheme, host and path components that are used by the URL pattern match algorithm have the following matching rules:

URL pattern component Matching rule for Web NFC Id
scheme exact match
host exact match or ends with (URL pattern's host prepended with ".").
path If URL pattern's path is "/*", match any Web NFC Id path. Otherwise, begins with URL pattern's path.

For example, 'https://mydomain.com/*' will match 'https://service.mydomain.com/myapp/' and 'https://info.mydomain.com/general/', while 'https://app.mydomain.com/contacts' will match 'https://app.mydomain.com/contacts' and 'https://app.mydomain.com/contacts/all' The '*' is a valid character for the URL path component, therefore, 'https://www.mydomain.com/*' pattern will match both 'https://www.mydomain.com/*' and 'https://www.mydomain.com/service' URLs.

URL pattern match algorithm

To match Web NFC Id with URL pattern for a given Web NFC Id and URL pattern, run these steps:
  1. Let raw id be a Web NFC Id passed to this algorithm.
  2. Let raw pattern be a URL pattern passed to this algorithm.
  3. If raw id and raw pattern are empty strings, return true.
  4. Let id be the result of running the basic URL parser on raw id.
  5. If id is failure, return false.
  6. Let pattern be the result of running the basic URL parser on raw pattern.
  7. If pattern is failure, return false.
  8. If id's scheme does not match pattern's scheme, return false.
  9. Let subdomain pattern be the result of prepending "." to pattern's host.
  10. If id's host does not end with subdomain pattern and id's host is not equal to pattern's host, return false.
  11. If pattern's path is equal to "/*", return true.
  12. If id's path begins with pattern's path, return true.
  13. Otherwise, return false.

The start() method

The section Receiving and parsing content uses NFCReader instances to match incoming NFC content.

Multiple consecutive calls to the start() method from the same origin create filters which are in OR relationship.

When the NFCReader.start method is invoked, the UA MUST run the following NFC listen algorithm:

  1. Let reader_instance be the NFCReader instance.
  2. If there is no underlying NFC Adapter, or if a connection cannot be established, then
    1. Let e be the result of creating a "NotReadableError" DOMException.
    2. Fire an event named "error" at reader_instance using NFCErrorEvent with its error attribute initialized to e.
    3. Return.
  3. Run the following steps in parallel:
    1. If the obtain reading permission steps return false, then
      1. Let e be the result of creating a NotAllowedError.
      2. Fire an event named "error" at reader_instance using NFCErrorEvent with its error attribute initialized to e.
      3. Return.
    2. If this is the first listener being set up, then make a request to all NFC adapters to listen to NDEF messages.
    3. If the request fails, then
      1. Let e be the result of creating a "NotSupportedError" DOMException.
      2. Fire an event named "error" at reader_instance using NFCErrorEvent with its error attribute initialized to e.
      3. Return.
    4. If the reader_instance.[[\Url]] is not an empty string and it is not a valid URL pattern, then
      1. Let e be the result of creating a "SyntaxError" DOMException.
      2. Fire an event named "error" at reader_instance using NFCErrorEvent with its error attribute initialized to e.
      3. Return.
    5. Add reader_instance to the activated reader objects.
    6. If the browsing context loses focus (e.g. the user navigated to another page), then the registered activated reader objects still SHOULD continue to exist, but SHOULD become paused, i.e. the UA SHOULD NOT check and use them until the focus is regained.

To obtain reading permission, run these steps:

  1. If there is a prearranged trust relationship, return true.
  2. Otherwise, if the user has earlier denied permission for the calling origin for all future calls of start() as well, then return false.
  3. Otherwise, UAs SHOULD ask for forgiveness with relevant information displayed to the user.

    The ask for forgiveness interaction might show choices like "block now" or "block forever", etc. If the user has chosen to "block forever" the given origin, it is the responsibility of the UA to remember these user choices for each origin, regardless of which NFC adapter is used, and consult them on later invocations.

    In this step UAs are advised to notify users about that reading NFC content may indirectly reveal the physical location of the user.

  4. Return true.

The stop() method

When the NFCReader.stop method is invoked, the UA MUST run the following algorithm:

  1. Remove the NFCReader instance from the activated reader objects.
  2. If the activated reader objects is empty, then make a request to stop listening to NDEF messages on all NFC adapters.

Receiving and parsing content

If there are any NFCReader instances in activated reader objects then UAs MUST listen to NDEF messages, according to step 3 of the NFC listen algorithm.

The NFC reading algorithm

When the UA is to receive NFC content it MUST run the following algorithm:

The UA SHOULD represent an unformatted NFC tag as an NDEF message containing a single empty NDEF record.

  1. If NFC is suspended, abort these steps.
  2. Let compatibility be "vendor" if the read NDEF compatible device is not officially supported by the NFC Forum, or else "universal".
  3. Let message be a new NDEFMessage object, with message's url set to null and message's records set to the empty list.
  4. Let serialNumber be the device identifier as a series of numbers, or null if unavailable.
  5. Set message's serialNumber to the string of U+003A (:) concatenating each number represented as ASCII hex digit, in the same order.
  6. Let input be the notation for the NDEF message which has been received.
  7. For each NDEF record which is part of input, run the following sub-steps for parsing NDEF record:
    1. Let ndef be the notation for the current NDEF record. The fields of ndef are described by the [[!NFC-STANDARDS]].
    2. Let record be a new NDEFRecord object.
    3. If ndef's TNF field is 0 (empty), then set record's recordType to "empty" and set record's mediaType to "".
    4. If ndef's TNF field is 1 (well-known type), and ndef's TYPE field is "T" (value 0x54 following NFC binary encoding), then run the following sub-steps for parsing NDEF Text record, or ensure that the underlying platform provides equivalent values to the record object properties:
      1. Let header be the first byte of ndef's PAYLOAD field.
      2. Let charset be "utf-8" if bit 7 (most significant bit) of header is equal to the value 0, or else "utf-16be".
      3. Let offset be the value given by bit 5 to bit 0 of the header.
      4. Let MIME type be a MIME type record with type "text", subtype "plain" and parameters equal to an empty ordered map.
      5. Let MIME type's parameters["lang"] be the result of running ASCII decode on second byte to the offset + 1 byte, inclusive.
      6. Set record's recordType to "text".
      7. Set record's mediaType to the result of serializing a MIME type with MIME type as the input.
      8. Let buffer be the byte sequence of ndef's PAYLOAD field, from position offset + 1 to the end.
      9. If charset is equal to "utf-8", set record's data to the result of running UTF-8 decode on buffer.
      10. Otherwise, set record's data to the result of running decode on buffer with encoding set to "utf-16be".

      Using the encoder from [[!ENCODING]], it is only possible to encode as UTF-8, unless you do the encoding manually and use the "opaque" recordType, which allows you to write any opaque data.

      When you write a string to the "text" recordType, it will be written as UTF-8. External applications have the ability to additionally encode this field as UTF-16BE, but that is transparent from the use of the NFCReader which will always return the data as a string.

      As external applications may have encoded the "opaque" recordType using a different encoding, which can be decoded using [[!ENCODING]] if you know the encoding.

    5. If ndef's TNF field is 1 (well-known type), and ndef's TYPE field is "U" (value 0x55 in NFC binary encoding), then run the following sub-steps for parsing NDEF URL record, or make sure that the underlying platform provides equivalent values to the record object properties:
      1. Set record's recordType to "url".
      2. Set record's mediaType to "text/plain".
      3. Let prefix code be the value of the first byte of ndef's PAYLOAD field.
      4. If prefix code is not 0, then set record's data to the prefix string obtained from mapping the value of prefix code to the URL prefix as specified in the [[!NFC-STANDARDS]] URI Record Type Definition specification, Section 3.2.2.
      5. Let buffer be the byte sequence of ndef's PAYLOAD field from the second byte to the end.
      6. Concat record's data with the result of running UTF-8 decode on buffer.
    6. If ndef's TNF field is 3 (absolute-URL string), then set record's recordType to "url", set record's mediaType to "text/plain" and set record's data to the string converted from ndef's PAYLOAD field.
    7. If ndef's TFN field is 2 (MIME type), then run the following sub-steps for parsing NDEF Media record, or make sure that the underlying platform provides equivalent values to the record object properties:
      1. Let MIME type be the MIME type record returned by running parsing a MIME type on ndef's TYPE field.
      2. If MIME type is a JSON MIME type, then
        1. Set record's recordType to "json".
        2. Set record's mediaType to the result of serializing a MIME type with MIME type as the input.
        3. Set record's data to the result of executing parse JSON from bytes on ndef's PAYLOAD field. If an error is thrown, skip to the next NDEF record.
      3. Otherwise,
        1. Set record's recordType to "opaque".
        2. Set record's mediaType to the result of serializing a MIME type with MIME type as the input.
        3. Set record's data to a new ArrayBuffer object constructed from the byte sequence of ndef's PAYLOAD field.
    8. If ndef's TNF field is 4 (external type), and ndef's TYPE field is urn:nfc:ext:w3.org:webnfc, then set message's url to the ndef's PAYLOAD field.
    9. Otherwise, if ndef's TNF field is 4 (external type), or 5 (unknown) then run the following sub-steps, or make sure that the underlying platform provides equivalent values to the record object properties:
      1. Set record's recordType to "opaque".
      2. If ndef's TYPE field is defined, then set record's mediaType to that string value, otherwise to "application/octet-stream".
      3. Set record's data to a new ArrayBuffer object constructed from the bytes of ndef's PAYLOAD field.
    10. Otherwise, skip to the next NDEF record in input.
    11. Append record to message's records.
  8. If NFC is not suspended and message's records is not empty, run the dispatch NFC content steps given message and compatibility.

Dispatching NFC content

To dispatch NFC content given a message of type NDEFMessage and compatibility of type NDEFCompatibility, run these steps:

  1. For each NFCReader instance reader_instance in the activated reader objects, run the following sub-steps:
    1. Let match be the result of running URL pattern match, with reader_instance.[[\Url]] as the URL pattern and message's url as the Web NFC Id.
    2. If match is false, continue.
    3. If reader_instance.[[\RecordType]] is present and it is not equal to any record.[[\RecordType]] where record is an element of message, continue.
    4. If reader_instance.[[\MediaType]] is not "" and it is not equal to any record's mediaType where record is an element of message, continue.
    5. If reader_instance.[[\Compatibility]] is not "any", and not equal to compatibility, continue.
    6. Fire an event named "reading" at reader_instance using NFCReadingEvent with its message attribute initialized to message.

Acknowledgments

The editors would like to thank Jeffrey Yasskin, Anne van Kesteren, Anssi Kostiainen, Domenic Denicola, Daniel Ehrenberg, Jonas Sicking, Don Coleman, Salvatore Iovene and Rijubrata Bhaumik for their contributions to this document.

Also thanks to Luc Yriarte and Samuel Ortiz for their initial work on exposing NFC to the web platform, and for their supports for the new approach.