<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pocket Factory</title>
    <description>The latest articles on DEV Community by Pocket Factory (@pocketfactory).</description>
    <link>https://dev.to/pocketfactory</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4203560%2F115998e6-5fff-4773-9c15-9099b2ec1b7f.png</url>
      <title>DEV Community: Pocket Factory</title>
      <link>https://dev.to/pocketfactory</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pocketfactory"/>
    <language>en</language>
    <item>
      <title>An NFC card at the register that opens your Instagram: the URL, iPhone vs Android, locking and the QR fallback</title>
      <dc:creator>Pocket Factory</dc:creator>
      <pubDate>Sat, 24 Oct 2026 19:32:35 +0000</pubDate>
      <link>https://dev.to/pocketfactory/an-nfc-card-at-the-register-that-opens-your-instagram-the-url-iphone-vs-android-locking-and-the-414b</link>
      <guid>https://dev.to/pocketfactory/an-nfc-card-at-the-register-that-opens-your-instagram-the-url-iphone-vs-android-locking-and-the-414b</guid>
      <description>&lt;p&gt;&lt;em&gt;I run Pocket Factory, which sells pre-programmed NFC cards, so I have a stake in this topic. Everything below works with a blank tag and a free app. You don't need to buy anything from me.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here's a common question for a coffee counter: "Can I leave a card by the register that opens our Instagram when someone taps it?" Yes. But a few details decide whether the card works for every customer or only for some of them. This post covers those details: what to write to the tag, how iPhone and Android handle it, how much memory you need, when to lock the tag, where to put it, and how to test it.&lt;/p&gt;

&lt;p&gt;If you've read my earlier post on &lt;a href="https://dev.to/pocketfactory/writing-a-google-review-link-to-an-nfc-tag-ntag213215216-with-a-qr-fallback-4lm3"&gt;writing a Google review link to an NFC tag&lt;/a&gt;, the chip side is the same. What's different here is the Instagram link and the coffee counter.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Decision&lt;/th&gt;
&lt;th&gt;Do this&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Link format&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;https://www.instagram.com/yourhandle/&lt;/code&gt; as an NDEF URI record&lt;/td&gt;
&lt;td&gt;iPhone background reading and Android both handle https; Instagram opens the app if it's installed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Don't use&lt;/td&gt;
&lt;td&gt;&lt;code&gt;instagram://user?username=...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;App-specific URL schemes aren't a reliable background-read target; customers without the app get nothing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clean the link&lt;/td&gt;
&lt;td&gt;Remove &lt;code&gt;?igsh=...&lt;/code&gt; and &lt;code&gt;?utm_source=qr&lt;/code&gt; from the share link&lt;/td&gt;
&lt;td&gt;Shorter payload, and you're not passing your own share-tracking token around&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chip&lt;/td&gt;
&lt;td&gt;NTAG213 is enough; NTAG215 gives headroom&lt;/td&gt;
&lt;td&gt;A profile URL is about 40 bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lock it?&lt;/td&gt;
&lt;td&gt;Yes, once it's tested&lt;/td&gt;
&lt;td&gt;A counter card is a public object; an unlocked tag can be rewritten by anyone with a phone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fallback&lt;/td&gt;
&lt;td&gt;A printed QR code with the same URL&lt;/td&gt;
&lt;td&gt;Covers phones with NFC turned off and iPhones older than the XS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Placement&lt;/td&gt;
&lt;td&gt;In a holder near the register, not on top of the payment terminal or on bare metal&lt;/td&gt;
&lt;td&gt;Metal detunes the tag, and two NFC targets side by side confuse people&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  1. Get the right Instagram link
&lt;/h2&gt;

&lt;p&gt;In the Instagram app, go to your profile, tap &lt;strong&gt;Share profile&lt;/strong&gt;, and copy the link. You'll get something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://www.instagram.com/yourcafe?igsh=MWx0bTNh...&amp;amp;utm_source=qr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Trim it to the canonical profile URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://www.instagram.com/yourcafe/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three reasons to trim it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Size.&lt;/strong&gt; The query string can double the payload.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Behavior.&lt;/strong&gt; The clean URL is what Instagram's app link handling expects. It opens the profile in the app when the app is installed and in the browser when it isn't.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hygiene.&lt;/strong&gt; &lt;code&gt;igsh&lt;/code&gt; is a share identifier tied to your share action. A card on a counter doesn't need it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Open the trimmed URL on your own phone before you write anything. If it doesn't land on your profile, fix it now.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Write it as an https URI record, not an app scheme
&lt;/h2&gt;

&lt;p&gt;It's tempting to write &lt;code&gt;instagram://user?username=yourcafe&lt;/code&gt; so the tap "goes straight to the app." Don't.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On iPhone, background tag reading (the mode where you just hold the phone near the tag with no app open) is built around URL records. Apple's &lt;a href="https://developer.apple.com/documentation/corenfc/adding-support-for-background-tag-reading" rel="noopener noreferrer"&gt;Core NFC background reading docs&lt;/a&gt; describe it working with universal links and a small set of system schemes. A random app scheme isn't something you can count on.&lt;/li&gt;
&lt;li&gt;If a customer doesn't have Instagram installed, an app-specific scheme dead-ends. An https link opens the web profile instead.&lt;/li&gt;
&lt;li&gt;An https link to instagram.com already opens the app on phones that have it, through universal links on iOS and app links on Android.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In NDEF terms you want a single &lt;strong&gt;URI record&lt;/strong&gt; (TNF 0x01, type &lt;code&gt;U&lt;/code&gt;) with prefix byte &lt;code&gt;0x04&lt;/code&gt; (&lt;code&gt;https://&lt;/code&gt;) followed by &lt;code&gt;www.instagram.com/yourcafe/&lt;/code&gt;. Every mainstream writer app does this for you when you choose "URL" or "Link". In &lt;strong&gt;NFC Tools&lt;/strong&gt; it's &lt;em&gt;Write → Add a record → URL/URI&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;One record only. Don't add a text record "for context" next to it. Some readers show a chooser or ignore the URL when there are several records, and that's the opposite of a one-tap experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. NTAG213 vs NTAG215 vs NTAG216
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Chip&lt;/th&gt;
&lt;th&gt;User memory&lt;/th&gt;
&lt;th&gt;Fits an Instagram profile URL?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;NTAG213&lt;/td&gt;
&lt;td&gt;144 bytes&lt;/td&gt;
&lt;td&gt;Yes, easily&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NTAG215&lt;/td&gt;
&lt;td&gt;504 bytes&lt;/td&gt;
&lt;td&gt;Yes, with lots of headroom&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NTAG216&lt;/td&gt;
&lt;td&gt;888 bytes&lt;/td&gt;
&lt;td&gt;Yes, but you're paying for memory you won't use&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;After the &lt;code&gt;0x04&lt;/code&gt; prefix byte, &lt;code&gt;www.instagram.com/yourcafe/&lt;/code&gt; is around 27–40 bytes depending on the handle. The NDEF and TLV overhead adds a handful more. Any of the three works. Pick on price, availability and card format, not memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Lock it after you test it
&lt;/h2&gt;

&lt;p&gt;A card on a café counter is a public object. If the tag is unlocked and has no password, anyone with a writer app can overwrite it with their own link. Most people never would. It only takes one.&lt;/p&gt;

&lt;p&gt;Testing order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write the URL.&lt;/li&gt;
&lt;li&gt;Test it on an iPhone and an Android phone (see the matrix below).&lt;/li&gt;
&lt;li&gt;Lock it. In NFC Tools this is &lt;em&gt;Other → Lock tag&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Locking is permanent.&lt;/strong&gt; You can't unlock it, and you can't change the link afterwards. If you ever change your handle, you replace the card. Treat that as a feature on a public counter.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Add the QR fallback
&lt;/h2&gt;

&lt;p&gt;NFC covers most phones, but not every customer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;iPhone XS or newer reads tags in the background. Older iPhones need the NFC reader in Control Center, and most people don't know it's there.&lt;/li&gt;
&lt;li&gt;On Android, NFC can be switched off in settings.&lt;/li&gt;
&lt;li&gt;Some people just prefer the camera.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So print a QR code of the &lt;strong&gt;same&lt;/strong&gt; trimmed URL on the card or holder. A few practical notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make it at least about 2 cm (0.8 in) across for a counter-distance scan.&lt;/li&gt;
&lt;li&gt;Use dark on light with a quiet zone around it. Don't put the code over your logo art.&lt;/li&gt;
&lt;li&gt;Scan it from roughly where the customer will stand, not from 10 cm away.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The printed line under it can be as plain as "Tap or scan to follow."&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Placement at a coffee counter
&lt;/h2&gt;

&lt;p&gt;What I've seen work at counters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Near the register, not on the payment terminal.&lt;/strong&gt; A customer who's just tapped their card to pay shouldn't have to guess which thing to tap next. Keep a hand's width between the terminal and the follow card, and label the follow card clearly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not on bare metal.&lt;/strong&gt; A tag lying flat on a stainless counter can read badly or not at all. Use an acrylic or wood holder, or a small stand, so there's a few millimetres of air or plastic underneath.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One card, one job.&lt;/strong&gt; If you also want Google reviews or tips, use separate cards with separate labels: follow at the register, review at pickup, tip link on the jar. One tag can only open one URL, and that's a good thing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where people wait.&lt;/strong&gt; The moment between paying and getting the drink is when people have a free hand and nothing to do.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A card or a stand? A stand reads from a step back and explains itself at a self-serve shelf. A card is flatter, cheaper, and fits next to a card reader on a crowded counter. Both run on the same chip and the same URL. I wrote a longer comparison of &lt;a href="https://getpocketfactory.com/blogs/news/instagram-nfc-stand-vs-card-for-coffee-shops?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=suave&amp;amp;utm_content=instagram-register-card" rel="noopener noreferrer"&gt;Instagram stands vs tap cards for coffee shops&lt;/a&gt; that includes other sellers.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Test matrix
&lt;/h2&gt;

&lt;p&gt;Run this once before you lock the tag, and once after you place it in its holder:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test&lt;/th&gt;
&lt;th&gt;Expected&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;iPhone XS or newer, screen on, Instagram installed&lt;/td&gt;
&lt;td&gt;Banner appears; tap opens your profile in the Instagram app&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same iPhone, Instagram not installed (or a friend's phone)&lt;/td&gt;
&lt;td&gt;Banner appears; opens instagram.com/yourcafe in Safari&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Android with NFC on, Instagram installed&lt;/td&gt;
&lt;td&gt;Opens the profile in the app (or a chooser the first time)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Android with NFC off&lt;/td&gt;
&lt;td&gt;Nothing happens. This is why the QR code is there&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;QR scan from customer distance&lt;/td&gt;
&lt;td&gt;Opens the same profile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phone in a thick case&lt;/td&gt;
&lt;td&gt;Still reads within about 1–2 cm; if not, move the tag up in the holder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tag sitting in the holder on the actual counter&lt;/td&gt;
&lt;td&gt;Same result as on the desk. If not, check for metal underneath&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  8. If you'd rather not build it
&lt;/h2&gt;

&lt;p&gt;The DIY route is a blank NTAG213 card, a free writer app and ten minutes. It's the cheapest option and works fine if you follow the steps above.&lt;/p&gt;

&lt;p&gt;If you want your logo printed on the card, the link written and locked before it arrives, and the QR printed on the back, that's what my company does. Pocket Factory makes &lt;a href="https://getpocketfactory.com/products/social-media-nfc-card?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=suave&amp;amp;utm_content=instagram-register-card" rel="noopener noreferrer"&gt;personalized NFC cards that open your Instagram&lt;/a&gt;, starting at $19 for one card with no subscription.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A printed QR backup is included by default.&lt;/li&gt;
&lt;li&gt;No battery or charging is needed.&lt;/li&gt;
&lt;li&gt;Cards work with iPhone XS or newer and NFC Android, with the QR backup for everything else.&lt;/li&gt;
&lt;li&gt;Cards ship from the USA, locked.&lt;/li&gt;
&lt;li&gt;Most standard orders are expected to be produced and shipped within approximately 3–5 business days; delays are possible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stand-style products from other sellers are a good fit if your counter has room and you want something readable from further away.&lt;/p&gt;




&lt;p&gt;Questions about NDEF records, a phone that won't read a tag, or a counter that's eating your signal? Ask in the comments. I'll answer the technical ones whether or not you're a customer.&lt;/p&gt;

</description>
      <category>nfc</category>
      <category>tutorial</category>
      <category>mobile</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Writing a Google review link to an NFC tag (NTAG213/215/216) with a QR fallback</title>
      <dc:creator>Pocket Factory</dc:creator>
      <pubDate>Sat, 24 Oct 2026 00:07:30 +0000</pubDate>
      <link>https://dev.to/pocketfactory/writing-a-google-review-link-to-an-nfc-tag-ntag213215216-with-a-qr-fallback-4lm3</link>
      <guid>https://dev.to/pocketfactory/writing-a-google-review-link-to-an-nfc-tag-ntag213215216-with-a-qr-fallback-4lm3</guid>
      <description>&lt;p&gt;Plenty of small businesses want a "tap here to review us" card or sticker at the counter. Doing it yourself takes a few dozen lines of JavaScript, a few cheap NTAG stickers and an Android phone. You do have to watch a few details: which URL you write, whether it fits on the chip, whether you lock the tag, and what happens when someone's phone has no NFC.&lt;/p&gt;

&lt;p&gt;This post covers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Getting the review link (and the &lt;code&gt;writereview&lt;/code&gt; URL format)&lt;/li&gt;
&lt;li&gt;NDEF byte math: will the URL fit on an NTAG213, 215 or 216?&lt;/li&gt;
&lt;li&gt;Writing the tag from a web page with Web NFC (&lt;code&gt;NDEFReader&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Locking the tag read-only&lt;/li&gt;
&lt;li&gt;Testing on iPhone and Android&lt;/li&gt;
&lt;li&gt;Generating a QR fallback with an open-source library&lt;/li&gt;
&lt;li&gt;Google's review rules in plain words&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclosure: I run a small shop that sells pre-programmed NFC cards (details at the end). Everything below works with any blank NTAG tag and free tools.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. Get the review link
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The official way
&lt;/h3&gt;

&lt;p&gt;Google Business Profile gives you the link directly. Google's help article &lt;a href="https://support.google.com/business/answer/16816815" rel="noopener noreferrer"&gt;Create a Google link or QR code to request reviews&lt;/a&gt; describes it: open your Business Profile, choose &lt;strong&gt;Read reviews → Get more reviews&lt;/strong&gt;, then &lt;strong&gt;Copy&lt;/strong&gt; the link or save the QR code. The same page notes that review QR codes can currently only be generated from a computer browser, not a phone.&lt;/p&gt;

&lt;p&gt;Use this link if you can. Google issues it, it points at your profile, and it's short, which matters for NFC (see section 2).&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;writereview&lt;/code&gt; URL (backup option)
&lt;/h3&gt;

&lt;p&gt;You'll also see this format used all over the web:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://search.google.com/local/writereview?placeid=YOUR_PLACE_ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It opens the "write a review" box for the place with that &lt;a href="https://developers.google.com/maps/documentation/places/web-service/place-id" rel="noopener noreferrer"&gt;Place ID&lt;/a&gt;. Two caveats:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google's review-link help page doesn't document this format. It's widely used and it works today, but it's community knowledge, not a promise. If Google changes it, every tag you've written with it breaks.&lt;/li&gt;
&lt;li&gt;You need the right Place ID. Google's Place ID page has a finder; search your business name and copy the ID exactly. Google says a truncated or modified Place ID is invalid, and that Place IDs can change over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My suggestion: write the link Business Profile gives you. Keep &lt;code&gt;writereview&lt;/code&gt; as a fallback for when you can't get into the profile (for example, you're setting up a tag for a friend's shop).&lt;/p&gt;

&lt;p&gt;Before writing anything, open the link on a phone that's &lt;strong&gt;not&lt;/strong&gt; signed in as the business owner. You should land on the review form or the profile with a review button, not on a sign-in wall or a "page not found."&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Will it fit? NDEF byte math
&lt;/h2&gt;

&lt;p&gt;NTAG213, 215 and 216 have 144, 504 and 888 bytes of user memory, per NXP's &lt;a href="https://docs.nxp.com/bundle/NTAG213_215_216/page/topics/block_description.html" rel="noopener noreferrer"&gt;NTAG213/215/216 product documentation&lt;/a&gt;. A URL is stored as an NDEF URI record, wrapped in a TLV block. For a short URL, the bytes look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;03 LL                 TLV: type 0x03 (NDEF message), length LL
D1 01 PL 55           record header: MB+ME+SR, TNF=1 (well-known), type length 1, payload length PL, type "U"
04                    URI prefix code (0x04 = "https://")
67 2E 70 61 ...       the rest of the URL as UTF-8 ("g.pa...")
FE                    terminator TLV
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The URI record type replaces common prefixes with one byte. The four you'll use:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Prefix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0x01&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://www.&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0x02&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://www.&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0x03&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0x04&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So for a short record the overhead is 2 (TLV) + 4 (header) + 1 (prefix code) + 1 (terminator) = 8 bytes. The &lt;code&gt;https://&lt;/code&gt; prefix is 8 characters and gets replaced by that one byte, so for an &lt;code&gt;https://&lt;/code&gt; URL &lt;strong&gt;the bytes on the tag come out equal to the URL's length&lt;/strong&gt; (4 fewer if it starts with &lt;code&gt;https://www.&lt;/code&gt;, which has its own prefix code). On an NTAG213 that means an &lt;code&gt;https://&lt;/code&gt; URL of up to 144 characters fits.&lt;/p&gt;

&lt;p&gt;Two thresholds add bytes on long URLs: once the record passes 254 bytes, the TLV length field grows to 3 bytes (+2), and once the payload passes 255 bytes, the record switches to the long format with a 4-byte payload length (+3). That only matters for NTAG215/216 and very long URLs.&lt;/p&gt;

&lt;p&gt;Here's a helper that does the math:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NFC Forum URI record prefixes we care about (index = prefix code)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PREFIXES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://www.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ndefUriBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// pick the longest matching prefix&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;PREFIXES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PREFIXES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;PREFIXES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;PREFIXES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PREFIXES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// prefix byte + URL bytes&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                      &lt;span class="c1"&gt;// short vs long record&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tlv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;254&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                          &lt;span class="c1"&gt;// 1-byte vs 3-byte TLV length&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;tlv&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                                    &lt;span class="c1"&gt;// + terminator 0xFE&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;NTAG213&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;144&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;NTAG215&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;504&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;NTAG216&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;888&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://search.google.com/local/writereview?placeid=ChIJxxxxxxxxxxxxxxxxxxxxxxx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ndefUriBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;chip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cap&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CAPACITY&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;cap&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`fits (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cap&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; bytes left)`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;too big&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That example URL is 79 characters and needs 79 bytes, so it fits on all three chips. Review links are short, so an NTAG213 is enough almost every time. Pick 215 or 216 only if you plan to store something else alongside the URL.&lt;/p&gt;

&lt;p&gt;One thing the math doesn't cover: whether your writing tool actually uses the prefix code. Most do, but check what landed on the tag with a reader app (section 5).&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Write the tag from a web page (Web NFC)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.chrome.com/docs/capabilities/nfc" rel="noopener noreferrer"&gt;Web NFC&lt;/a&gt; launched in Chrome 89 for Android. It doesn't exist on iPhone or desktop browsers, so the writing step needs an Android phone. Per Chrome's docs, it only works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;on HTTPS pages (or localhost), in a top-level frame,&lt;/li&gt;
&lt;li&gt;when called from a user gesture like a button click,&lt;/li&gt;
&lt;li&gt;while the page is visible and the phone is unlocked.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A minimal writer page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"url"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"url"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"https://..."&lt;/span&gt; &lt;span class="na"&gt;size=&lt;/span&gt;&lt;span class="s"&gt;"60"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"write"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Write tag&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"log"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;log&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;write&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NDEFReader&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Web NFC isn't available here. Use Chrome on Android over HTTPS.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// throws on a malformed URL&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;That doesn't look like a full URL.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ndef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NDEFReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hold the tag against the back of the phone...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ndef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;records&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;recordType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Written. Now test it with a different phone.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Write failed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;recordType: "url"&lt;/code&gt;, not &lt;code&gt;"text"&lt;/code&gt;. A text record shows the URL as text; it doesn't open it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;write()&lt;/code&gt; overwrites whatever is on the tag by default. If you're writing a batch and want to skip tags that already have data, pass &lt;code&gt;{ overwrite: false }&lt;/code&gt; and the promise rejects if the tag already holds an NDEF message.&lt;/li&gt;
&lt;li&gt;The browser asks for NFC permission the first time.&lt;/li&gt;
&lt;li&gt;Where the antenna sits varies by phone. If nothing happens, slide the tag slowly around the back of the phone.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Lock the tag (optional, permanent)
&lt;/h2&gt;

&lt;p&gt;A tag sitting on a counter can be rewritten by anyone with an NFC app, unless you lock it. Chrome 100+ on Android adds &lt;code&gt;makeReadOnly()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"lock"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Lock tag (permanent)&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// reuses log() from the writer page above&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NDEFReader&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;makeReadOnly&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;NDEFReader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lock&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ndef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NDEFReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hold the tag against the phone to lock it...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ndef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;makeReadOnly&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// resolves after the user taps the tag&lt;/span&gt;
      &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tag is now permanently read-only.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Lock failed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lock&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// needs Chrome 100+ on Android&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can't be undone. Only lock a tag after you've tested it on both platforms and you're sure the URL won't change. If you think you might switch links later, leave it unlocked, or point the tag at a URL on your own domain that redirects to Google, so you can change the destination without touching the tag. Keep the redirect a plain redirect, with no rating screen in between (see section 7).&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Test on iPhone and Android
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Android:&lt;/strong&gt; NFC has to be switched on in settings. With the screen on and unlocked, a tap on a URL tag opens the link.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;iPhone:&lt;/strong&gt; According to Apple's &lt;a href="https://developer.apple.com/documentation/corenfc/adding-support-for-background-tag-reading" rel="noopener noreferrer"&gt;background tag reading docs&lt;/a&gt;, iPhone XS and later read NDEF tags in the background, without an app, while the iPhone is in use (screen on). Apple lists exceptions: not before the first unlock after a restart, not while Apple Pay, Wallet or the camera is in use, and not in Airplane Mode. A banner appears and tapping it opens the URL. Older NFC-capable iPhones (7, 8, X) don't read tags in the background; they need the NFC Tag Reader control in Control Center (iOS 14 or later) or a reader app. Phones without NFC can't tap at all, which is what the QR fallback in section 6 is for.&lt;/p&gt;

&lt;p&gt;A checklist I use:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the tag with a reader app (NXP's TagInfo or NFC Tools) and confirm the record is a URI record with the exact URL, with no extra spaces or a stray &lt;code&gt;http://&lt;/code&gt; prefix.&lt;/li&gt;
&lt;li&gt;Tap with an Android phone that has never visited the link.&lt;/li&gt;
&lt;li&gt;Tap with an iPhone XS or newer, unlocked.&lt;/li&gt;
&lt;li&gt;Tap through a phone case and, if the tag will be stuck on something, on that surface. Metal behind an ordinary tag can stop it from reading; use on-metal tags there.&lt;/li&gt;
&lt;li&gt;Do it signed out of Google, so you see what a customer sees.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  6. QR fallback
&lt;/h2&gt;

&lt;p&gt;Some phones don't have NFC, some have it switched off, and some people just don't know to tap. Put a QR code of the &lt;strong&gt;same URL&lt;/strong&gt; next to the tag.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/soldair/node-qrcode" rel="noopener noreferrer"&gt;node-qrcode&lt;/a&gt; library (MIT licensed) does this in a few lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;qrcode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;QRCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;qrcode&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://search.google.com/local/writereview?placeid=ChIJxxxxxxxxxxxxxxxxxxxxxxx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// PNG for quick printing&lt;/span&gt;
&lt;span class="nx"&gt;QRCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;review-qr.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;errorCorrectionLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;M&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// SVG for print shops (scales without blurring)&lt;/span&gt;
&lt;span class="nx"&gt;QRCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;errorCorrectionLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;M&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;review-qr.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep the quiet zone (&lt;code&gt;margin: 4&lt;/code&gt;). Cropping the white border is the most common reason printed codes won't scan.&lt;/li&gt;
&lt;li&gt;Dark modules on a light background. Inverted codes fail on some scanner apps.&lt;/li&gt;
&lt;li&gt;Don't print it tiny. Test-scan the printed code from the distance people will actually stand.&lt;/li&gt;
&lt;li&gt;Add a short line like "Tap or scan to leave a review", so people know both options exist.&lt;/li&gt;
&lt;li&gt;Google's Business Profile can also give you a ready-made review QR code (from a computer browser), if you'd rather not generate one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more on how tap cards behave on different phones, I wrote up &lt;a href="https://getpocketfactory.com/blogs/news/do-nfc-review-cards-work-on-iphone-and-android?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=suave&amp;amp;utm_content=nfc-review-tag-tutorial" rel="noopener noreferrer"&gt;which phones read NFC review cards and why some don't&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And if you're still deciding whether a printed review card is worth it at all, I also wrote up &lt;a href="https://getpocketfactory.com/blogs/news/what-is-a-google-review-card?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=suave&amp;amp;utm_content=google-review-card" rel="noopener noreferrer"&gt;what a Google review card is, and what it doesn't do&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Google's review rules in plain words
&lt;/h2&gt;

&lt;p&gt;The tech is the easy part. What gets reviews removed is how you ask. From the &lt;a href="https://support.google.com/contributionpolicy/answer/7400114" rel="noopener noreferrer"&gt;Maps user-generated content policy&lt;/a&gt; and the &lt;a href="https://support.google.com/business/answer/16816815" rel="noopener noreferrer"&gt;review link help page&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No incentives.&lt;/strong&gt; No payment, discounts, or free goods or services in exchange for a review, or for changing or removing a negative one. Google calls this fake engagement, and those reviews get removed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No gating.&lt;/strong&gt; Don't ask only the customers you think are happy, and don't put a "How did we do? 1–5 stars" screen in front of the link that sends only 4–5 star people to Google. Google doesn't allow merchants to "selectively solicit positive reviews."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't pressure or script.&lt;/strong&gt; Don't require a review on the spot, don't tell people what to write, and don't give staff review quotas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do ask everyone the same way.&lt;/strong&gt; Hand the card to every customer, or leave it at the counter. That's fine and it's what Google's own help page suggests (receipts, thank-you emails, a QR code in the store).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice: write the plain review URL to the tag, with no intermediate rating page, and offer it to everyone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Get the link from Business Profile → &lt;strong&gt;Get more reviews&lt;/strong&gt;. &lt;code&gt;writereview?placeid=&lt;/code&gt; is a backup.&lt;/li&gt;
&lt;li&gt;For &lt;code&gt;https://&lt;/code&gt; URLs, the bytes on the tag ≈ the URL length. NTAG213 = 144 bytes.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NDEFReader.write({ records: [{ recordType: "url", data }] })&lt;/code&gt; on Android Chrome 89+.&lt;/li&gt;
&lt;li&gt;Test on both platforms, then &lt;code&gt;makeReadOnly()&lt;/code&gt; (Chrome 100+) if you won't need to change the URL.&lt;/li&gt;
&lt;li&gt;Print a QR code of the same URL as a fallback.&lt;/li&gt;
&lt;li&gt;No incentives, no gating.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  If you'd rather not program tags yourself
&lt;/h2&gt;

&lt;p&gt;I run &lt;a href="https://getpocketfactory.com/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=suave&amp;amp;utm_content=nfc-review-tag-tutorial" rel="noopener noreferrer"&gt;Pocket Factory&lt;/a&gt;, which makes personalized NFC cards with your logo, pre-programmed with your link (a Google review link, booking page, website or menu). They use an NTAG215 chip and ship locked, so the link can't be changed later; a new link means new cards. No battery or charging is needed, and a printed QR backup is included by default. The DIY route above works just as well if you have an Android phone and some blank tags.&lt;/p&gt;

&lt;p&gt;If you build a small writer page from this, I'd like to hear what tags and phones you tested on.&lt;/p&gt;

</description>
      <category>nfc</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
