From e72e6f2ec5a8dad34acb3a827ce8422859914a89 Mon Sep 17 00:00:00 2001 From: Usman Baig Date: Fri, 6 Mar 2026 19:25:05 +0100 Subject: [PATCH] feat: add AI traffic source identification Display proper brand icons and names for AI referrers (ChatGPT, Perplexity, Claude, Gemini, Copilot, DeepSeek, Grok, Meta AI, You.com, Phind) in Top Referrers panel. --- CHANGELOG.md | 4 ++++ lib/utils/icons.tsx | 26 ++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f51b4d..6edade6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ## [0.13.0-alpha] - 2026-03-02 +### Added + +- **AI traffic source identification.** Pulse now automatically recognizes visitors coming from AI tools — ChatGPT, Perplexity, Claude, Gemini, Copilot, DeepSeek, Grok, Meta AI, You.com, and Phind. These sources appear in your Top Referrers with proper brand icons and display names instead of raw domain URLs. If someone clicks a link in an AI chat to visit your site, you'll see exactly which AI tool sent them. + ### Improved - **Cleaner internal API code.** The analytics data-fetching layer has been streamlined — 13 near-identical endpoint functions were consolidated using a shared pattern, cutting roughly half the code while keeping every feature working exactly as before. This makes it easier to add new analytics endpoints in the future and reduces the chance of inconsistencies between them. diff --git a/lib/utils/icons.tsx b/lib/utils/icons.tsx index da7f3cd..f3cca87 100644 --- a/lib/utils/icons.tsx +++ b/lib/utils/icons.tsx @@ -30,7 +30,8 @@ import { FaGlobe } from 'react-icons/fa' import { FaXTwitter } from 'react-icons/fa6' -import { SiBrave } from 'react-icons/si' +import { SiBrave, SiOpenai, SiPerplexity, SiAnthropic, SiGooglegemini } from 'react-icons/si' +import { RiRobot2Fill } from 'react-icons/ri' import { MdDeviceUnknown, MdSmartphone, MdTabletMac, MdDesktopWindows } from 'react-icons/md' export function getBrowserIcon(browserName: string) { @@ -79,7 +80,17 @@ export function getReferrerIcon(referrerName: string) { if (lower.includes('github')) return if (lower.includes('youtube')) return if (lower.includes('reddit')) return - + // AI assistants and search tools + if (lower.includes('chatgpt') || lower.includes('openai')) return + if (lower.includes('perplexity')) return + if (lower.includes('claude') || lower.includes('anthropic')) return + if (lower.includes('gemini')) return + if (lower.includes('copilot')) return + if (lower.includes('deepseek')) return + if (lower.includes('grok') || lower.includes('x.ai')) return + if (lower.includes('phind')) return + if (lower.includes('you.com')) return + // Try to use a generic globe or maybe check if it is a URL return } @@ -111,6 +122,17 @@ const REFERRER_DISPLAY_OVERRIDES: Record = { quora: 'Quora', 't.co': 'X', 'x.com': 'X', + // AI assistants and search tools + openai: 'ChatGPT', + perplexity: 'Perplexity', + claude: 'Claude', + anthropic: 'Claude', + gemini: 'Gemini', + copilot: 'Copilot', + deepseek: 'DeepSeek', + grok: 'Grok', + 'you': 'You.com', + phind: 'Phind', } /**