Setup Links
This skill builds or migrates your link-in-bio page at "/links" to align with the RDF standard. It ensures a static, noindex/follow page with precise click tracking, i18n support, and required footer links.

What it does
This skill constructs your product's "/links" page, intended for use in social profiles. It implements the organization-wide RDF standard structure, featuring 3-6 buttons, one highlighted, all ordered by business value. The page is static, noindex/follow, and tracks clicks without PII, while adapting to your repository's existing helpers for translations, metadata, and analytics.
When to use it
-
When you need to create a new link-in-bio page for your product's social profiles.
-
When you need to migrate an existing link-in-bio page (internal or from third-party services like Linktree) to the product's standard.
-
When you want to ensure your link-in-bio page adheres to specific technical requirements (tracking, i18n, SEO) and compliance guidelines.
How to set it up
-
Copy the skill's definition file into your repository under .claude/skills/setup-links/setup-links.md.
-
Invoke the skill in Claude Code by typing "/setup-links".
The content
Setup Link-in-Bio Page
Build this product's /links page in the one form every RDF web product
uses: the page the social profiles link to.
Contract reference: load .claude/ref/growth/link-in-bio.md first. It is
the single source of truth — this skill only executes it. Reference
implementation: padel-league.richi.solutions.
Context probes:
Monorepo web app: ![ -f apps/web/package.json ] && echo "apps/web" || echo "none (single app)"
Framework: !for d in apps/web .; do [ -f "$d/package.json" ] || continue; grep -q '"next"[[:space:]]*:' "$d/package.json" && echo "next ($d)" && break; grep -q '"vite"[[:space:]]*:' "$d/package.json" && echo "vite ($d)" && break; done
App Router dir: !ls -d apps/web/src/app apps/web/app src/app app 2>/dev/null | head -1 || echo "none"
Existing link page: !find app src/app apps/web/app apps/web/src/app src/pages -path '*links*' -name 'page.tsx' 2>/dev/null | head -5; grep -rln '"/links"' src 2>/dev/null | head -5
Locale segment: !ls -d app/\[locale\] src/app/\[locale\] apps/web/app/\[locale\] 2>/dev/null || echo "single-locale"
Locales: !ls src/i18n/locales apps/web/src/i18n/locales 2>/dev/null | tr '\n' ' '
Analytics: !grep -o '"@vercel/analytics"' package.json apps/web/package.json 2>/dev/null | head -1 || echo "no @vercel/analytics"
Funnel registry: !ls src/domain/funnels.ts src/lib/funnel.ts 2>/dev/null || echo "none"
Templates: !ls .claude/skills/setup-links/templates/next 2>/dev/null && echo "present" || echo "MISSING — sync .claude first"
Step 0: Eligibility
Stop and report if this repo has no public web surface (mobile-only .app.
repos, backend/automation repos, behind-auth-only tools). Work on a feature
branch in a worktree (/new-worktree feat/links-page). In a monorepo every
path resolves under apps/web/.
Step 1: Inventory
Read and note before writing:
- An existing link page (probe above) or third-party link page (Linktree etc. — ask the user for the current bio URL if unknown). Record its buttons and order; a migration keeps them unless the user says otherwise.
- The repo's helpers for: server-side translation, page metadata, locale
routing (
localizedPath/asLocale), the analytics facade, the funnel registry (if any). - Imprint and privacy page paths (
legal-pages.md); stop and report if either is missing — the page must link both. - The brand logo (a ≤ 96 px WebP; create one from the existing logo with
sharpif absent) and the brand colour tokens (Tailwind theme).
Step 2: Decide the Buttons
Propose to the user, in one message: 3–6 buttons (id, label, destination), which one is highlighted and why, and the order — by business value (contract §4). Wait for confirmation before writing. Mark affiliate destinations as sponsored.
Step 3: Copy the Templates (Next)
Copy every file from .claude/skills/setup-links/templates/next/ to the same
relative path (drop .tmpl; app/ → the App Router dir; without a
[locale] segment use app/(bio)/links/page.tsx). Then adapt:
| Template | Map to |
|---|---|
@/i18n/server getServerT | the repo's server translation helper |
@/lib/seo/metadata buildPageMetadata | the repo's metadata builder (canonical + hreflang); else a plain Metadata object with alternates.canonical |
@/lib/seo/locale-routes | the repo's locale routing; single-locale: drop params/locale, use plain paths |
@vercel/analytics track | the repo's analytics facade |
@/lib/funnel funnelStep | keep if the repo has a funnel registry; otherwise remove funnelStep, BioPageView and the funnel assertions in the test |
__PRODUCT_NAME__ | the product name |
bg-primary / bg-accent … | the repo's brand tokens |
Fill ITEMS, HIGHLIGHT, SPONSORED and BioTarget from Step 2, and
replace the TODO(setup-links) comment with the reasoning for the order.
Do not change the mechanics (static, noindex/follow, structure order, click
event shape, sponsored rel). A deviation needs a documented reason in the
file.
Vite exception repos: build the same structure as a route rendered
outside the app layout, with <meta name="robots" content="noindex,follow">;
reuse BioLink.tsx without "use client".
Step 4: Wire It
- Funnel registry (if present): add the
linksfunnel — stepview, one outcome per button id (contract §5). - i18n: add the
links.*keys (contract §4) to every locale file; run the repo's key-parity test. - Routes:
/linksstays out ofPUBLIC_ROUTESand out ofEXCLUDED_PREFIXES. If the repo keeps a list of page paths for locale routing (e.g. content routes), add/linksthere. - Middleware / chrome: confirm the route group renders no site header, footer, nav, chat widget or banner other than the consent banner.
- Remove the legacy: delete an old link page and redirect its URL to
/linksinnext.configredirects().
Step 5: Verify
npm run lint,npm run typecheck,npm run test,npm run build— green; the build lists/linksas static (○ or ●).npm run start, open/links(and one other locale) at 390 px width: structure order, one highlight, every button reaches its destination, imprint/privacy present,<meta name="robots" content="noindex, follow">in the HTML, no site chrome.- Walk the contract checklist (§8) and report each item.
Final Step: Commit and Hand Over
Commit with a body, e.g.:
feat: add the link-in-bio page at /links
Static /links page for the social profiles, outside the site chrome and
noindexed: <n> buttons led by <highlight>, clicks reported as
bio_link_click and in the links funnel without PII. Follows the
org-wide link page standard (ref/growth/link-in-bio.md).
Report to the user: the buttons in order, and that after deploy the bio of
every social profile must point to https://<product-domain>/links.
Served straight from the framework this site runs on. This page always shows the current version.
Missing a skill you cannot find here?
Then let us talk. I also build skills tailored to your team and your workflows.