---
title: "Pure Internet: NFC"
section: posts
description: "HTML, CSS & minimal JS combined with NFC tech to create serverless web experiences."
tags: ["web-development", "nfc", "data-urls", "html", "ipfs", "egg", "decentralized-web"]
created: 2024-11-18T10:55:00Z
updated: 2025-05-23T14:09:00Z
cid: bafkreie5ij7rghiderfncm6auo77ico5ybud2wf2c6usd6m2ljdh24ezli
html: https://iammatthias.com/posts/1731984900000-pure-internet-nfc
---

# Pure Internet: NFC

Strip the web back to HTML, CSS, and a sprinkle of JavaScript. No build process, no stylesheets, no dependencies.

What if you put it on an NFC card?

## NFC

Most modern phones can read NFC. Beyond contactless payments and transit cards, NFC can carry arbitrary data through NDEF (NFC Data Exchange Format) records.

The limits matter: a few kilobytes of storage per tag, and iOS handles NFC differently from Android. iOS only honors specific record types and demands an explicit user tap. Android reads more record types and supports background scanning.

## Data URLs

Data URLs encode a file inline, usually as base64. They've been around forever, mostly for small images in CSS:

```
background-image: url(data:image/png;base64,iVBORw0KGgo...)
```

Since 2017, browsers refuse data URLs for top-level navigation. Good for security, fatal for the original idea.

## First attempt

Plan A: store an entire website as base64 on an NFC card. Tap to open. No server.

Top-level navigation said no. Users can still copy and paste, but tap-to-open is dead:

```
data:text/html;base64,PHRpdGxlPk9mZmxpbmU8L3RpdGxlPjxib2R5PjxoMT5PZmZsaW5lPC9oMT48cD5UaGlzIGlzIGEgd2ViIHBhZ2UsIGJ1dCBpdCdzIG5vdCBvbmxpbmUuPC9wPjxwPkl0IGlzIGVuY29kZWQgaW4gdGhlIFVSSSwgd2hpY2ggaXMgc3RvcmVkIG9uIHRoZSBORkMgY2FyZCB5b3UganVzdCBzY2FubmVkLjwvcD48cD5UaGFuayB5b3UgZm9yIHZpc2l0aW5nLjwvcD48L2JvZHk%2B
```

The `file://` scheme hits the same security wall. Raw HTML text records need manual handling. Custom MIME types confuse most readers.

## ENS + IPFS

Workaround: ENS name, an HTML file pinned to IPFS, an iframe to render the data URL, an NFC card storing an [eth.limo](http://eth.limo) URL, and base64 content in the hash.

The HTML:

```
<!doctype html>
<html>
  <head>
    <title>PURE INTERNET</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
  </head>
  <body>
    <iframe id="f"></iframe>
    <script>
      const iframe = document.getElementById("f");
      iframe.src = location.hash
        ? `data:text/html;base64,${location.hash.slice(1)}`
        : "data:text/html;base64,PHA+UFVSRSBJTlRFUk5FVDwvcD4=";
    </script>
  </body>
</html>
```

Encode the page as base64. Stick it on the NFC card as part of an [eth.limo](http://eth.limo) URL like `https://pureinternet.eth.limo/#VGhpcyBpcyBQdXJlIEludGVybmV0`. Tap loads the IPFS-pinned HTML through ENS. The script pulls the base64 from the hash and renders it in the iframe, which sidesteps the top-level data-URL block.

## Is this pure internet?

Probably the closest you can get. IPFS and ENS are still infrastructure, but the rest is HTML, CSS, JS, and a tag in your hand.

The hash trick generalizes. Any page can carry its content in the URL itself: no database, no storage, content that exists only as long as the URL does.

---

## Related

- [Pure Internet](https://iammatthias.com/posts/1731955749292-pure-internet.md): Pure Internet is a running collection of small experiments in publishing with fewer layers.
- [Mint thyself](https://iammatthias.com/posts/1685948400001-mint-thyself.md): A Zora HTML edition that embeds its own mint interface and can be minted from itself.
- [Obsidian Pinata Image Uploader](https://iammatthias.com/open-source/1744172723728-obsidian-pinata-image-uploader.md): Upload Obsidian images to Pinata with automatic IPFS URI conversion and gateway proxying for clean display and referencing.
- [Pure Internet: no-html](https://iammatthias.com/posts/1740682611811-pure-internet-no-html.md): A plain Markdown file hosted on Bluesky's blob storage and rendered directly by the browser.
- [orbz dot com](https://iammatthias.com/posts/1736537615834-orbz-dot-com.md): orbz.fun reads Orbiter's onchain site registry and turns it into a StumbleUpon-style discovery tool.
