Skip to content
Product

Portage

A link in bio that search engines can actually read

Portage is the studio's free link-in-bio tool. One address for everything a person makes, rendered on the server as a real indexable document, dressed in generated landscape art, and instrumented with analytics that use no cookies at all.

Status
Live at portage.camp · Free, no paid tier
Year
2026 – present

Portage in use

A Portage share card: a generated lake landscape at golden hour above a name, a tagline and four link chips
Fig. 01 — Portage

01Brief

The problem

A link-in-bio page is the highest-intent link most people own, and the category renders it in the browser from a JSON payload — so it is a blank document to a crawler, invisible to the answer engines that increasingly sit between a question and a click, and mute about who it belongs to. Meanwhile the features that make one worth keeping, from click analytics to scheduled links, are the paid tier. Portage inverts both halves.

02Measured

By the numbers

The figures that describe the shape of the build. Each one was read off the shipped product itself.

8

landscapes, all contrast-measured

56

colour pairs checked by script

0

cookies set, on any page

03Process

The build

Decision by decision: how it is put together, and what each one bought.

  1. The page is HTML before it leaves the server

    A server component, deliberately against the grain of the category. The name is an h1, the links are real anchors, the structured data is in the document rather than assembled after paint, and the whole page works with JavaScript switched off. Every page carries a ProfilePage node, a Person or Organization with the owner's profiles in its sameAs, and an ItemList of the links in order — which is the vocabulary an index uses to decide that a name on a page and a name in its records are one entity.

  2. Eight landscapes, drawn by the build

    Each theme is a place rather than a colour scheme: a sky, a sun or moon, star fields, aurora ribbons, ridgelines receding into haze, a procedurally-drawn treeline where no two spruces match, water with a scattered light path, and a canoe. All of it is generated vector art from a seeded PRNG, so a scene is a few kilobytes, identical on every render, and sharp from a 72px picker thumbnail to a 1200px share card. One generator feeds the page banner, the social card and the editor, so a theme cannot look one way in the editor and another way when somebody shares it.

  3. Every colour is the owner's, and the consequence is measured

    Six tokens are exposed, not one, and the editor measures five contrast pairs live against the same function that gates a release — so somebody changing their palette is told the moment their body text stops being readable, rather than discovering it in daylight. The eight presets ship measured too: 56 pairs, checked by a committed script that exits non-zero on a failure.

  4. Free means the paid tier's features

    Inline YouTube, Spotify, SoundCloud and Vimeo players; email capture with CSV export; links that appear and disappear on a schedule; uploaded avatars and banners; a vCard button; a print-ready QR code; and analytics with referrers, devices, countries and a daily chart. The one thing that is not free is removing the footer credit, because that credit is the entire distribution plan and the page says so.

  5. Counting people without following them

    A visitor is a truncated HMAC of address, user agent, handle, a server secret and the date — enough to separate two people today, meaningless tomorrow, and the address is never stored. There is no cookie, so a Portage page needs no consent banner, and both Do Not Track and Global Privacy Control are honoured, which costs real numbers and is the point.

  6. Its own domain, for a reason that is not branding

    An open publishing surface on cadenic.studio would put the studio's own search presence behind strangers' behaviour. portage.camp is served by the same deployment and the same Vercel project, with one middleware file mapping both hosts and enforcing that every page has exactly one address — so the blast radius belongs to the product rather than to the studio, and Portage can compete for its own terms without dragging the studio's site away from its subjects.

04Screens

Every screen here was captured from the shipped build and cropped, never mocked up. Each plate is cut to its own capture, so nothing here has been squared off to fit a grid.

Fig. 02A published page. The banner is generated vector art, and every link is a real anchor in the HTML.
Fig. 03Eight places, not eight colour swatches. The same generator draws the banner, the picker and the share card.
Fig. 04The product page previews the real renderer rather than a screenshot, so it cannot drift from the product.

05Stack

What it runs on

The tools in production, grouped by the job they do.

Application
  • Next.js 16
  • React 19
  • TypeScript
  • Tailwind CSS v4
Data
  • PostgreSQL
  • Supabase
  • JSONB documents
  • Row-level security
Rendering
  • Server components
  • Generated SVG
  • Satori
  • ISR
Identity
  • Passwordless email
  • HMAC sessions
  • Resend
Distribution
  • JSON-LD
  • Dynamic OG images
  • llms.txt
  • QR codes

Next project — Product

A chronicle for the games you actually watched