What can Web NFC write, and what can it not?
Any NDEF message, from text and links to MIME data and external types, formatting a blank tag on the way, and from Chrome 100 a permanent lock. Nothing below NDEF: no password, no configuration page, no raw command. And a failed write reports only that it failed, so the page reads the tag back before trying again.
What write() does
write() prepares a message and waits for a tag. In the Chrome article on Web NFC, its promise resolves once the user taps a tag and the message is written, under the same conditions as a scan: a user gesture, the permission, and NFC present and switched on.
A plain string becomes a text record, in UTF-8 and in the document's language unless the record says otherwise. Anything else is a message of records: a URL, an absolute URL, MIME data, a smart poster, an external type such as example.com:foo, or an empty record.
That covers what most tags carry. It also covers an Android Application Record, which the article writes as the external type android.com:pkg, with the limits described on the application record page.
Tags that already hold a message
By default, the write replaces whatever the tag holds. The specification sets overwrite to true unless told otherwise; set to false, the write reads the tag first and rejects with NotAllowedError if it finds NDEF records.
A blank tag is handled for you. When the tag in range is unformatted and can be formatted for NDEF, the specification formats it, then writes. The article adds that such a tag reads as a single empty record, which is how a page can recognise one before writing.
The specification recommends calling write() from a reading event, so that the page checks the existing content or the serial number and writes only to the tag it meant to write.
Locking from a page
makeReadOnly() arrived in Chrome 100 on Android, and the article describes it as a one way process that cannot be reversed. Test for it with 'makeReadOnly' in NDEFReader.prototype before offering it.
Tie it to a separate action from the write, taken after the content has been checked on a second phone. Whether to lock at all is decided on the locking page.
What a page cannot do
Web NFC stops at NDEF by design. The article lists what is out of scope: low level operations such as ISO-DEP, NFC-A, NFC-B and NFC-F, peer to peer, and host card emulation.
That rules out everything a chip does beyond storing a message. A page cannot set or use a password, write a configuration page, enable a counter or read a signature, all of which go through raw commands.
A failed write also says little. The specification rejects with NetworkError when the transfer fails, without saying how far it got, so read the tag back before trying again. The article's read after write example, a write() followed by a short scan(), does exactly that.
Frequently asked questions
Can Web NFC set a password on a tag?
No. Passwords are set with chip commands, and Web NFC stops at NDEF: low level operations are outside its scope.
What happens if the tag already holds a message?
By default it is overwritten. With overwrite set to false, the write reads the tag first and rejects if it finds NDEF records.
Can a page make a tag read only?
From Chrome 100 on Android, with makeReadOnly. The lock is permanent, so it belongs after the content has been checked.
Why did my write fail with NetworkError?
The specification raises it when the transfer to the tag fails. Read the tag back before retrying, since the page cannot tell how far the write went.