Overview
Mercenary was a link-in-bio service sign up, claim a username, and get a fully customizable public profile page at `mercenary.lol/yourname`. It's the same category as Linktree or guns.lol, but leaned much further into visual customization: backgrounds, embedded audio, cursor effects, badges, and profile-wide theming. It grew to 1,000+ users before being taken offline.
Per-User Pages via Dynamic Routing
Every user's profile lived at their own slug `mercenary.lol/shadow` powered by Next.js dynamic routes. A single `[username]/page.tsx` handled every profile on the platform: it reads the `username` param, looks up that user's document in Firestore, and renders their page using whatever customization data comes back. No separate page or deploy per user; the route is the template and Firestore is the content.
Data Model
Each user is a single Firestore document holding everything about their profile in one place: display name, bio, colors, background type and media, badge visibility, link list, and a nested `customization` map for the newer effects. Uploaded media (profile pictures, banners, background video, audio) is stored as URLs pointing to Firebase Storage and Cloudflare R2, referenced directly from the document rather than duplicated anywhere.
{
"username": "shadow",
"displayName": "Shadow",
"background_type": "solid",
"background_color": "#000000",
"links": { "Discord": "https://discord.gg/...", "Custom": "https://..." },
"badge_visibility": { "Premium": false, "Famous": true }
}Customization System
The customization surface grew into a large set of independently toggleable effects layered on top of the base profile: gradient and hex-gradient container backgrounds, blur and opacity controls, card tilt, glare, a color-wave effect, typewriter text, sparkle and rain overlays, custom cursors, and a full badge system (owner, staff, developer, verified, premium, and more) with configurable order and placement. Each effect is stored as its own field or boolean flag on the user document, so the render layer just walks the document and conditionally applies whatever's turned on.
Analytics
Basic analytics were tracked per profile: total view count, a weekly views array (a rolling 7-slot counter), and per-link click counts keyed by link name, so users could see which of their links actually got clicked. A `recentActivity` log recorded a timestamped history of profile edits.
Challenges
- Designing a Firestore document schema flexible enough to support a constantly growing list of visual effects without a rigid migration every time a new feature shipped
- Keeping a single dynamic route performant while rendering a wide range of very different, heavily customized profile layouts
- Handling user-uploaded media (images, video backgrounds, audio) reliably across Firebase Storage and external hosts
Status
Mercenary is no longer active mercenary.lol is currently offline and the project isn't maintained. It's included here as a portfolio piece for the engineering behind it, not as a live product.
