Skip to main content

/writing

Designing URLs for a Printed QR Code

· 2 min read

I built the companion site for a book that is going to print. Every chapter carries a QR code linking to that chapter’s song.

That one sentence contains the hardest constraint of the project. Once the book ships, the URL behind every code is frozen. You cannot patch paper. URL stability stops being a preference and becomes a contract with objects you will never be able to reach again.

Two ways a URL dies

The first threat is the host. The site deploys to a GitHub Pages project page under a repo path, which would tie every printed code to a vendor and a path prefix. The answer is a domain I own. If the host ever changes, that is one DNS update, and the printed codes never notice.

The second threat is the path. The obvious route shape comes from the song title, and titles get edited. What does not change is the track number, so each song lives at /t/01 through /t/10. Nothing anyone might rename appears in the path.

Short paths help on paper too. Fewer characters means a sparser QR code, and a sparser code scans better on a smudged page.

The subtle decision was in how the codes get generated. They are built at build time as SVGs, and they encode a hardcoded permanent origin rather than reading the framework’s site config.

Reading the config would bake whatever it happened to say into every physical copy, and for most of the project it said a temporary GitHub Pages URL. Instead the codes point at the permanent domain from the start. They were correct on paper before that domain resolved at all, which felt wrong and was not. It means the book can go to print on its own schedule rather than waiting on the site.

The codes use error correction level H, which survives roughly thirty percent damage. Paper smudges and books get carried around.

What I learned

A printed QR code is an API with one consumer you can never migrate. Design the URL the way you would design a public contract: nothing mutable in the path, no coupling to a host, and pin the target to the value that has to be true in five years rather than the one that is true today.