Skip to content

Add username availability lookup across 50+ platforms - #3

Open
hyepr wants to merge 17 commits into
developmentfrom
claude/handle-lookup-implementation-g5ifm
Open

Add username availability lookup across 50+ platforms#3
hyepr wants to merge 17 commits into
developmentfrom
claude/handle-lookup-implementation-g5ifm

Conversation

@hyepr

@hyepr hyepr commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR adds a complete username/handle lookup feature that checks availability across 50+ social media, developer, gaming, creative, and professional platforms. Users can search for a handle and get real-time results showing which platforms have that username available or taken.

Key Changes

  • Platform Configuration (src/lib/platforms.ts): Added comprehensive platform definitions with 50+ services organized by category (social, developer, gaming, creative, music, writing, professional). Each platform includes detection logic for unavailable usernames via status codes, response messages, or URL patterns.

  • Lookup Logic (src/lib/lookup.ts): Implemented core checking functionality that:

    • Validates usernames against platform-specific regex patterns
    • Fetches profile URLs with proper headers and timeouts
    • Detects availability using three strategies: HTTP status codes, response body messages, or redirect URLs
    • Returns results with response times for performance tracking
  • API Endpoint (src/app/api/lookup/route.ts): Created Server-Sent Events (SSE) streaming endpoint that:

    • Validates incoming handle parameter
    • Streams results as each platform check completes (instead of waiting for all)
    • Provides real-time progress feedback to the client
  • Results UI (src/components/lookup-results.tsx): Built interactive results page with:

    • Live streaming results with skeleton loaders
    • Color-coded status badges (available/taken/unknown)
    • Search bar for quick re-checks
    • Response time metrics
    • Direct links to each platform profile
  • Lookup Page (src/app/lookup/[handle]/page.tsx): Added dynamic route for handle results with proper metadata generation

  • Lookup Form (src/components/lookup-form.tsx): Extracted reusable search form component used on homepage

  • Layout Updates (src/app/layout.tsx, src/components/hero.tsx): Integrated new lookup form into hero section and cleaned up font configuration

  • Build Config (next.config.ts): Added experimental Turbopack TLS configuration for improved build performance

Implementation Details

  • Uses Promise.allSettled() to check all platforms in parallel while handling individual failures gracefully
  • Implements 10-second timeout per request to prevent hanging on slow/unresponsive platforms
  • Supports platform-specific request headers (e.g., Accept-Language for Twitter/X)
  • Streams results via SSE for responsive UX without blocking on slowest platforms
  • Includes username format validation (e.g., Telegram requires 5+ chars starting with letter)

https://claude.ai/code/session_011nbTf3SpFDiLh1LkHfrxow

claude added 2 commits March 25, 2026 08:02
- Add 40+ platform configs (platforms.ts) using Sherlock's detection approach — status code, message match, and response URL patterns
- Add parallel checker (lookup.ts) with per-platform timeout and SSE streaming callback
- Add /api/lookup SSE route that streams results as each platform check completes
- Add /lookup/[handle] results page with progressive card rendering and skeleton loading
- Add LookupForm client component wired to the hero search bar
- Wire hero.tsx to use the functional LookupForm

https://claude.ai/code/session_011nbTf3SpFDiLh1LkHfrxow
Replace next/font/google imports with plain CSS fallbacks and enable
turbopackUseSystemTlsCerts to work around the sandboxed build environment
where fonts.googleapis.com is unreachable.

https://claude.ai/code/session_011nbTf3SpFDiLh1LkHfrxow
@vercel

vercel Bot commented Mar 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
handlelookup Ready Ready Preview, Comment Mar 26, 2026 1:24am

@coderabbitai

coderabbitai Bot commented Mar 25, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 33b2ebc8-5b6a-4282-9b38-06a44f77cb65

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/handle-lookup-implementation-g5ifm

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

…, Geist font

- Font: Restored Geist via npm package (geist/font/sans + geist/font/mono) — fixes broken system font fallback
- Platforms: Replaced manual list with all 459 non-NSFW platforms from Sherlock's data.json (status_code/message/response_url detection, urlProbe, POST support, regexCheck)
- Lookup service: Added concurrency limiter (50 parallel requests) and full Sherlock compatibility (urlProbe, POST payloads, custom headers, errorCode overrides)
- Homepage: All lookup UI now lives on / — form updates ?q= param via nuqs, LookupResults reads it and streams SSE
- Category filter: pill tabs (All, Featured, Social, Developer, Gaming, Creative, Music, Writing) derived from live results, persisted in ?category= URL param
- Results: Cards animate in (fade + slide) as each platform check completes, progress bar, skeleton placeholders, color-coded Available/Taken/Unknown badges
- Default state: Shows featured platform preview grid before any search
- /lookup/[handle] redirects to /?q=handle

https://claude.ai/code/session_011nbTf3SpFDiLh1LkHfrxow
Features:
- Business category: LinkedIn, ProductHunt, Patreon, Gumroad, Ko-fi, BuyMeACoffee, Freelancer, Trello, Wix
- Rate limiting: 5 lookups/day for unauthenticated (server-side, in-memory per IP); unlimited for Clerk auth users
- /api/lookup/status endpoint returns remaining lookups + auth state
- Availability filter dropdown (All / Available / Taken / Unknown) via nuqs ?status=
- Platform name search input with 250ms throttle via nuqs ?search=
- shadcn Pagination (12 cards/page) with ellipsis for many pages, via nuqs ?page=
- shadcn Progress bar (h-0.5, fades out when done)
- Filter toolbar: search + status select + limit badge in one row; category pills in row below
- Category pills show live result counts as checks stream in
- All filters (category, status, search, page) work together seamlessly; page resets to 1 on filter change
- Smooth handle transition: grid remounts with fade-in when q changes (keyed div)
- Fetch+AbortController replaces EventSource for proper 429 detection
- Hero: restored DecorIcon corner marks + FullWidthDivider at bottom
- Cards only appear after a handle is entered (no default preview grid)
- Micro-interactions: card hover lift + shadow, button ExternalLink opacity, pill active:scale-95, smooth transitions

https://claude.ai/code/session_011nbTf3SpFDiLh1LkHfrxow
… counts; add motion animations

- Hero: remove duplicate FullWidthDivider (kept single top divider with corner DecorIcons)
- Lookup results: remove manual ChevronDown from SelectTrigger (shadcn renders its own)
- Platforms: add Twitter/Instagram/YouTube/TikTok/Pinterest to Business category
- Category pills: show count only in shadcn Badge, not duplicated in label text
- Add motion/AnimatePresence for smooth crossfade between searches and staggered card entrances

https://claude.ai/code/session_011nbTf3SpFDiLh1LkHfrxow
- Full responsive: form full-width on mobile, filter row stacks on sm, grid 1→2→3 cols
- Category pills: negative margin bleed to screen edges on mobile with overflow scroll
- Pagination: wraps on small screens
- Animations: reduced to y:6/y:8, duration 0.18-0.2, cubic-bezier ease, less intrusive
- Idle state: mono hint text shown before any lookup ("↑ enter a handle…")
- Empty state: icon + heading + subtext + clear filters button (replaces plain text)
- Rate-limit state: same icon + heading pattern as empty state
- LookupForm: @ prefix in input, full-width with flex-1 input, cleaner submit button
- ResultCard: ghost button for view link, mono URL text, softer hover shadow
- Hero: removed duplicate comment, adjusted mobile padding, removed <br /> in subtitle
- Progress bar: h-px (thinner, less obtrusive)

https://claude.ai/code/session_011nbTf3SpFDiLh1LkHfrxow
…rcent counter

- Revert ResultCard to original outline button "View on {platform}" style
- Restore px-4 md:px-8 padding on results wrapper (was removed last commit)
- Category pills: clean overflow-x-auto without negative margin hack; no scrollbar shown
- Remove Progress bar; replace with monospace percentage counter (e.g. "42%") in stats row
- LookupForm: keep @ prefix input, consistent padding

https://claude.ai/code/session_011nbTf3SpFDiLh1LkHfrxow
Rate limiting:
- All lookups now require authentication (401 for unauthenticated requests)
- Free authenticated users: 5 lookups/day, keyed by Clerk userId
- Pro subscribers (has({ plan: 'user:pro' })): unlimited, no rate limit applied
- rate-limit.ts: simplified to userId-only store, exports DAILY_LIMIT constant

API:
- /api/lookup: requires auth, checks Clerk Billing Pro plan before rate-limiting
- /api/lookup/status: returns { authenticated, isPro, unlimited?, remaining?, limit? }

New components:
- AuthGate: shown when unauthenticated user submits a handle — value-first sign-in
  prompt with free plan features, "Start free" + sign-in CTAs
- UpgradeDialog: auto-opens on rate limit hit — amber icon, live reset countdown,
  Pro feature list, price, "Upgrade to Pro" CTA; psychological triggers: loss
  framing (reset timer), value anchoring (459 platforms), risk reduction (cancel anytime)

lookup-results.tsx:
- useAuth() gate: AuthGate shown instead of firing lookup when not signed in
- rateLimited state auto-opens UpgradeDialog + shows amber fallback state
- LimitBadge: progressive coloring (green→amber→red), clickable at 0 to open dialog
- LimitInfo type updated with isPro field

Pricing page:
- Replaced Polar-based PricingSection with clean plan comparison cards
- Clerk's <PricingTable> embedded for one-click subscription checkout
- Free vs Pro feature lists, pricing shown clearly, "Most popular" badge on Pro

Header:
- Fetches /api/lookup/status on mount for signed-in users
- Pro users: shows "Pro" badge instead of Upgrade button
- Free signed-in users: "Upgrade" button with Zap icon linking to /pricing
- Unauthenticated: "Sign in" + "Start free" buttons

https://claude.ai/code/session_011nbTf3SpFDiLh1LkHfrxow
- Require auth for all lookups (401 for unauthenticated)
- Free users: 5 lookups/day stored in Clerk private metadata (tamper-proof)
- Pro users (user:pro plan): unlimited lookups, bypasses rate limit
- Global upgrade drawer (Dialog desktop / Drawer mobile) with PricingTable
- Upgrade drawer launched from header button and on rate limit hit (429)
- AuthLoadingState skeleton prevents layout shift when q param in URL
- Fix post-auth redirect URLs to / instead of /app/profile
- Extract DAILY_LIMIT constant to shared lib/constants.ts

https://claude.ai/code/session_011nbTf3SpFDiLh1LkHfrxow
… drawer

- pricing: replace custom plan cards with SectionShell + PricingTable only;
  full-width dividers and corner deco icons restored via SectionShell
- upgrade-drawer: simplify UI (less visual noise), close overlay the moment
  the Clerk subscribe button is clicked so checkout sheet isn't obscured
- providers: drop unused `handle` state from UpgradeDrawerCtx
- lookup-results: fix Clerk loading flag (`!isLoaded` not `!isLoaded && !!q`)
  so idle hint still shows during initial auth load, skeleton shows when q set
- app/loading.tsx: add Next.js route-level loading spinner for navigation

https://claude.ai/code/session_011nbTf3SpFDiLh1LkHfrxow
- upgrade-drawer: remove limitReached prop entirely; single generic UI
  ("Upgrade to Pro / Unlimited lookups across all platforms")
- providers: simplify context to plain openUpgrade() with no arguments
- lookup-results: replace inline AuthGate with router.push redirect to
  /sign-up?redirect_url=/?q={handle} so users return to same handle
  after auth; remove auto-open upgrade drawer on 429; clean rate-limited
  empty state (neutral colors, outline button "Upgrade plan"); remove
  amber coloring from LimitBadge; openUpgrade() called with no args
- delete auth-gate.tsx (no longer needed)

https://claude.ai/code/session_011nbTf3SpFDiLh1LkHfrxow
hyepr added 6 commits March 25, 2026 23:40
…date header and hero section imports; enhance pricing page layout
… from Page, enhance user experience with conditional rendering
- Updated breadcrumb structure in pricing page for better formatting
- Added missing semicolon in providers.tsx
- Simplified card descriptions in avatar and email components
- Consolidated query state initialization in blog page client
- Enhanced badge rendering in blog post card
- Reformatted footer links for consistency
- Improved header component structure and formatting
- Adjusted hero component styles for better alignment
- Standardized spacing and formatting in lookup form and results components
- Refined mobile navigation for better user experience
- Cleaned up pricing card imports for clarity
- Enhanced upgrade dialog drawer layout
- Streamlined user dropdown rendering
- Improved lookup library functions for better readability
- Updated platform keys for better organization
- Corrected JSON formatting in sherlock-data.json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants