Link-in-bio pages, on the same links you already have
· 7 min read
shrtn.ink now hosts link-in-bio pages. You claim a handle, you get shrtn.ink/@yourhandle, and you can have three of them per account. They are free, on the same plan as everything else here, and there is no upgrade that unlocks their analytics or their API.
That last sentence is the reason the feature exists at all. A link-in-bio page is, structurally, a list of links with a photo above it — and a shortener is already a thing that owns links and measures them. Building the page on top of the links I already had was less work than building it beside them, and it means the page inherits everything the links could already do rather than getting a second, worse version of it.
The links on the page are just short links
Each link you add to a page gets a real short link behind it. Not a lookalike, not a separate table — the same row, on the same redirect path, going through the same handler as a link you shortened by hand. So the per-link analytics were not a feature I had to add: referrers, devices, locations and the human-versus-bot split were already there, and the page's links land in the same 30-day dashboard as the rest.
It also means the numbers mean the same thing. A click on a page link is measured by the code that measures every other click, so there is no second definition of “click” to reconcile and no chance of the two drifting apart. Reuse is usually argued for on effort. The better argument here is that one implementation cannot disagree with itself.
Why the handle can never collide with a slug
The obvious problem with adding /@handle to a service whose whole job is /{id} is that both are one path segment. If someone shortens a link to the slug @alice, whose route wins?
Neither, because that slug cannot exist. The slug charset excludes @, for custom back-halves as well as generated ones, so a stored slug can never begin with it. The two namespaces are disjoint by construction rather than by a check somebody has to remember to write. On top of that, matchit, the router underneath tako, resolves a prefixed parameter like /@{handle} ahead of a bare /{id} — so even the routing order is decided by the router, not by registration order I could get wrong later.
I mention this because it is the kind of decision that is cheap while the feature is a sketch and expensive once there are pages in the wild. A collision here would not have been a bug to fix; it would have been someone's page and someone else's link wanting the same URL, with no answer that does not take something away from one of them.
Three pages, not unlimited
The cap is deliberate and it is not about storage. Handles are a single shared namespace: every account draws from the same pool of names, and the good ones are finite. With no cap, one account can register the obvious brand names and the common words in an afternoon, and everyone who arrives later finds the namespace already spent.
Three is enough to keep a page per project — a personal one, a band, a side business — and small enough that bulk registration is not worth the trouble. If you genuinely need more, that is a conversation rather than a checkout.
Pages that stay out of search
A page is listed in search by default. If you would rather it was not, you can turn that off: the page is then marked for search engines not to index it, both in the document and in the response headers, and it keeps working exactly as before for anyone you hand the link to.
Worth being precise about what that is and is not. It keeps a page out of results for crawlers that respect the instruction, which is what the major search engines do. It is not a password and it is not privacy — the page is still a public URL, and anyone with the link can open it. If you need something stronger than “not indexed”, this is not it.
The API, and the MCP tools
The pages are in the public API on the same bearer key as the rest of it: list your pages with their contents, create one, update it, delete it, and read its statistics. Nothing about the page is only reachable through the dashboard, which matters more than it sounds — a page you cannot read programmatically is a page you cannot migrate away from, and a free feature you cannot leave is not really free.
There are MCP tools over the same surface, so an assistant can read a page, edit it and pull its stats without anyone writing glue. They are scoped to reading and updating on purpose: creating and deleting pages stay in the dashboard, because a handle is a name in a shared namespace and a deletion cascades to the page's links.
Reporting a page
A free service that hosts pages of outbound links will be used for things it should not be, so the abuse channel covers pages, not just links. If you find a shrtn.ink page pointing somewhere malicious, report it the same way you would report a short link.
Links on a page are scanned against Google Safe Browsing like every other link on the service — at write time, and again lazily as they age. Putting a link on a page does not route it around that.
What the pages do not do
No storefront, no email capture, no scheduled publishing. Those are real features that real products have, and they are not on the way — they are a different kind of product from a shortener, and doing them badly next to something that works would make both worse.
A page holds up to fifty items in total, links, text and images alike, and one page belongs to one account. The editor writes as you type and shows the page beside it while you do. That is the whole feature: a page of links you already trust the numbers on.
If you want to see what one looks like, the feature page shows a page beside the editor that produces it, and compares the whole thing against the alternatives. Or you can claim a handle and see it from the inside.