Short links with retargeting pixels attached, plus a link-in-bio page. The selling point is that a click passes through your own domain so an advertising pixel can fire before the visitor lands.
Build me short links with retargeting that replace Switchy: a click passes through my own domain, a pixel fires, and then the visitor lands. STACK - Node 20+ with Fastify - SQLite through better-sqlite3, WAL mode - Caddy in front with on-demand TLS for custom domains - The redirect path is one indexed lookup and nothing else BEFORE THE SPECIFICATION, THE HONEST PART - This category exists to add somebody to an advertising audience when they click a link — often a link to a page that is not yours at all. The visitor did not ask for that and usually cannot tell it happened - In the EU and the UK, firing an advertising pixel needs consent, and consent means a real choice before the tag runs, not a banner on the destination you do not control - So build it with a consent gate, keep the interstitial honest and fast, and do not pretend a redirect through your domain is invisible. A tool that quietly audiences everyone who clicks a shared link is the thing this catalogue exists to be sceptical of - Then decide, deliberately, whether you want it. The link shortening and the analytics below are worth having either way THE DATA MODEL - domains: id, hostname, workspace_id, is_verified, certificate_state, default_redirect - links: id, domain_id, slug, destination, title, tags_json, utm_json, pixel_ids_json, interstitial_kind, expires_at, password_hash, is_active, created_by, created_at - link_versions: id, link_id, destination, changed_by, at — appended, never overwritten - pixels: id, workspace_id, network, tag_id, consent_required, is_active - clicks: id, link_id, at, referrer_host, country, device, browser, os, lang, ip_hash, bot, is_preview, consent_state, matched_rule_id - rules: id, link_id, kind, match_json, destination, position — geography, device, language, time - bio_pages: id, workspace_id, slug, title, bio, avatar_path, theme_json, is_active - bio_links: id, bio_page_id, label, url, icon, position, is_active, clicks THE REDIRECT - 302, never 301. A cached permanent redirect can never be re-pointed, and re-pointing is the whole reason for a short link - Answer in a couple of milliseconds: one lookup from an in-memory table, respond, record after - Without pixels, it is a bare redirect and nothing renders. That is the fast path and it should be the default - With pixels, a minimal interstitial page fires the tags and then moves on — under 200ms of blocking, with a visible skip link and a hard timeout so a slow network tag never traps the visitor. Never a five-second countdown with an advert on it - Never redirect to a `javascript:` or `data:` destination; validate the scheme on save CONSENT - A consent gate before any advertising tag: a short, honest choice, remembered for the session - Declining still redirects, immediately, with no tag fired. A gate that punishes a decline is not a gate - The consent state recorded on the click, so you can say later what was and was not collected - Configurable per country, because the rules differ, and defaulted to asking THE DOMAIN - Add a hostname, verify by DNS, and let Caddy's on-demand TLS issue a certificate - The ask endpoint must check the hostname against the domains table before requesting a certificate. Without that check, anybody pointing a domain at your server makes you request certificates on their behalf and you hit the issuer's rate limits within the hour - A default redirect for the bare domain DEEP LINKS - Open the native application where it is installed, fall back to the web page otherwise - On iOS this is fiddly and behaves differently inside in-app browsers; test on a real device rather than assuming - Record which path was taken, so the fallback rate is visible THE BIO PAGE - A page of links with an avatar, a short line and a theme - Server-rendered, under 50KB, no framework, fast on a phone on a poor connection — this page is opened from a social application, which is the worst browsing environment there is - Clicks counted per link through the same redirect machinery - Open Graph tags and a generated share image CLICKS, COUNTED HONESTLY - Bots flagged, never dropped, and excluded from published numbers through a SQL view. Social and chat applications fetch every link that is posted, and counting those makes a launch look like a success - A preview fetch is identifiable from the user agent and from the timing - Unique clicks by a salted hash of address and user agent within a window, with the definition written next to the number - By day, referrer, country, device and language, computed at query time SAFETY - Destinations checked against a malware list on save if one is configured, and reported links queued for review. An open short-link service is a phishing tool, and yours will be found within weeks of being public - Rate limits on creation per key and per member OPERATIONS - .env: DATABASE_PATH, BASE_URL, HASH_SALT, SESSION_SECRET, GEOIP_DB_PATH - Migrations on boot, each once - Country from a local database file, never an external API - Nightly backup off the machine — a lost link table breaks every link anybody has shared - Health endpoint that resolves one link WHAT MATTERS MOST Redirect speed and the consent gate. Build the bare-redirect fast path first, then add the interstitial with a hard timeout and a real choice. If the pixel makes the link slow or the choice fake, you have built something worse than the thing you were replacing. Give me the repository, migrations, .env.example, the Caddy configuration with the ask endpoint, and a README with deploy steps, the DNS records, and the consent position stated plainly.
What you lose
- Retargeting pixels for a dozen ad networks, already wired and maintained as each one changes its tag
- A hosted link-in-bio page with themes
- Deep links that open the native app on a phone rather than the browser
- Somebody else keeping up with the consent rules that apply to firing a pixel
If you would rather not build
- A Cloudflare Worker plus a static bio page
- Linktree, if the bio page is all you actually wanted
What it costs
as published on their pricing page
| Plan | Billed monthly | Billed yearly | Last read |
|---|---|---|---|
| — | $9/mo | — | — |
Their pricing page is where these came from. Seeing a different price? Tell us.
The escape hatch
open source · no votes, no paid placement
LittleLink
$0A static link-in-bio page you host yourself; no database at all.
sethcottle/littlelinkfree · open source
Why this verdict
our own opinion · changed only by a person
88/100
Verdict yes at 88. The build is a redirect and a handful of script tags. What genuinely does not come for free is keeping a dozen ad networks' tags current, which is why the moat is worded the way it is.
History
tracked since 10 Aug 2026 · nothing is ever overwritten
Questions about Switchy
answered from the record above
Is Switchy free?
No — the plan we track is $9 a month. Pro at $9/month billed monthly, around $6 annually.
Can you replace Switchy by building your own?
YES. Replaceable in one session with an AI coding agent. Replacement score 88 out of 100, build time one session. Read what you lose before you decide.
How much does Switchy cost?
$9 a month on Pro — $108 a year. Recorded 9 Aug 2026.
What do you lose by replacing Switchy?
Retargeting pixels for a dozen ad networks, already wired and maintained as each one changes its tag; A hosted link-in-bio page with themes; Deep links that open the native app on a phone rather than the browser; Somebody else keeping up with the consent rules that apply to firing a pixel. If any of those carry weight for you, keep paying.
Is there an open-source alternative to Switchy?
Yes: Dub, LittleLink. The prompt on this page is for when you want it your way instead.
Related entries
same category first, most replaced first
Every week, something stops being worth paying for.
New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.
free forever · no tracking pixel · stored here, never passed to anyone

