pickuma.
Meta

How Our /go Affiliate Redirect and Click Tracking Actually Works

A walkthrough of the database-backed redirect, UTM tagging, and click logging behind every affiliate link on Pickuma — and why we never hardcode a vendor URL.

6 min read

Every affiliate link on this site points at one place: /go/<slug>. You never see a raw vendor URL with a tracking parameter glued on the end in our MDX. That single layer of indirection is the difference between a blog that can swap a partner program in thirty seconds and one that has to grep through 490 articles to fix a dead link. Here is exactly what happens between the click and the vendor.

The redirect path, slug by slug

When you click a tool link, the request hits a single dynamic route: /go/[slug]. The slug is the only thing the link carries — notion, cursor, beehiiv, and so on. The route does one job: look that slug up in a Supabase table called affiliate_links, read the destination URL and the link’s status, and respond.

The response depends on the status column:

  • active → a redirect to the real affiliate URL, with UTM parameters attached.
  • paused → an HTTP 410 Gone. Not a 404, not a silent redirect to the homepage. A 410 tells search engines and link checkers that the resource is deliberately retired, which keeps crawlers from hammering a link we’ve turned off.

The URL itself lives in the database, never in the article. That matters more than it sounds. Affiliate programs change their tracking URLs, migrate between networks like Reditus and PartnerStack, and occasionally revoke an approval. When that happens we update one row in Supabase. Every article that mentions that tool — footer links, inline cards, the /tools/<slug> hub page — points at the new destination on the next request. No rebuild, no content edit, no risk of a stale ?ref= parameter sitting in a post from eight months ago.

Why the click gets logged before the redirect

The redirect isn’t the whole job. Before /go/<slug> sends you onward, it writes a row to a clicks table: the slug you clicked, a timestamp, and the country the request came from. That’s it — no fingerprinting, no cookie, no cross-site identifier. Three columns.

That tiny log is what turns affiliate income from a black box into something you can actually reason about. You can pull the last fifty clicks straight from the database and see which tools people are clicking, when, and roughly from where:

curl -sX GET "$SUPABASE_URL/rest/v1/clicks?select=slug,ts,country&order=ts.desc&limit=50" \
  -H "apikey: $SUPABASE_SERVICE_ROLE_KEY" \
  -H "Authorization: Bearer $SUPABASE_SERVICE_ROLE_KEY"

The click log is our copy of the truth. Affiliate dashboards report conversions on their own schedule and with their own attribution windows; some don’t show you a raw click count at all. By logging the click on our side at redirect time, we always know how much interest a tool is getting independent of what the partner network chooses to surface. If our clicks count for a slug is healthy but the partner reports nothing, that’s a signal something is broken on their end — a tracking URL that changed, an approval that lapsed — and we go look.

UTM tags: the same click, attributed by surface

The redirect doesn’t just forward you. It appends UTM parameters so that whatever analytics the destination feeds into — and our own GA4 — can split traffic by where the click originated. The same tool can be linked from several surfaces, and each gets its own campaign tag:

Surfaceutm_sourceutm_medium
Article footer (tools mentioned)article-footerinternal
Tool hub CTA (/tools/[slug])tool-hubinternal
Bluesky crosspost cardblueskysocial
dev.to body footer linkdevtocrosspost

This is why the indirection earns its keep a second time. Because every link routes through /go, the UTM convention is applied in one place instead of being copy-pasted (and mistyped) across hundreds of posts. One rule about how a Bluesky click should be tagged, enforced centrally.

Two sources of truth, kept in sync

There’s a subtlety worth naming. The redirect reads from Supabase, but the UI — the footers, the /tools directory, the inline cards — reads from a TypeScript file, src/data/affiliates.ts. That’s deliberate: the site is statically built, so the components need their data at build time, while the redirect needs it at request time.

The rule that keeps this from rotting is simple: change both. Add an affiliate, and it goes into the Supabase affiliate_links table and into affiliates.ts. Pause one, and you flip the status in the database and remove it from the TypeScript file so it stops appearing in footers and the tools directory. Drift between the two is the one failure mode this design can’t catch on its own, so it’s the one thing we check by hand.

If you run something similar, keep a written record of which slug maps to which program and network — it’s the kind of operational map that lives well in a shared doc.

Notion

Where we keep the affiliate inventory map — slug, program, network, approval status, and the last time each tracking URL was verified. A single source of operational truth alongside the code.

Free for personal use; paid plans from $10/user/mo

Try Notion

Affiliate link · We earn a commission at no cost to you.

FAQ

Why not just put the affiliate URL directly in the article?+
Because affiliate URLs change. Networks migrate, tracking parameters get reissued, and approvals get revoked. A direct URL in a published post means editing the post every time that happens — across hundreds of articles. Routing through /go/<slug> means one database row controls every link to that tool.
What data does the click log actually store?+
Three things: the slug you clicked, a timestamp, and the country the request came from. No cookies, no cross-site identifiers, no personal data. It exists so we can measure interest in a tool independently of what the affiliate network reports.
What happens when an affiliate link is retired?+
We set its status to 'paused' in the database. The /go route then returns HTTP 410 Gone instead of redirecting, which tells crawlers the link is intentionally gone. We also remove it from affiliates.ts so it disappears from footers and the tools directory.

None of this is exotic. It’s one dynamic route, one lookup table, one three-column log, and a discipline about never hardcoding a vendor URL. But that small amount of structure is what lets a catalog of hundreds of reviews stay swappable, measurable, and honest about where its money comes from.

Related reading

See all Meta articles →

Get the best tools, weekly

One email every Friday. No spam, unsubscribe anytime.