Add username availability lookup across 50+ platforms - #3
Conversation
- 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
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
…, 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
…integrate upgrade dialog drawer
…date header and hero section imports; enhance pricing page layout
…cross multiple files
… 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
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:API Endpoint (
src/app/api/lookup/route.ts): Created Server-Sent Events (SSE) streaming endpoint that:Results UI (
src/components/lookup-results.tsx): Built interactive results page with:Lookup Page (
src/app/lookup/[handle]/page.tsx): Added dynamic route for handle results with proper metadata generationLookup Form (
src/components/lookup-form.tsx): Extracted reusable search form component used on homepageLayout Updates (
src/app/layout.tsx,src/components/hero.tsx): Integrated new lookup form into hero section and cleaned up font configurationBuild Config (
next.config.ts): Added experimental Turbopack TLS configuration for improved build performanceImplementation Details
Promise.allSettled()to check all platforms in parallel while handling individual failures gracefullyhttps://claude.ai/code/session_011nbTf3SpFDiLh1LkHfrxow