diff --git a/CHANGELOG.md b/CHANGELOG.md
index 737ec67..b0d4eaa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,12 @@ All notable changes to Pulse (frontend and product) are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and Pulse uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html) with a **0.x.y** version scheme while in initial development. The leading `0` indicates that the public API and behaviour may change until we release **1.0.0**.
+## [0.5.1-alpha] - 2026-02-12
+
+### Changed
+
+- **Top Referrers: X icon instead of Twitter bird.** Referrers from x.com and t.co now show the X logo instead of the legacy bird.
+
## [0.5.0-alpha] - 2026-02-11
### Added
@@ -45,7 +51,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
---
-[Unreleased]: https://github.com/ciphera-net/pulse/compare/v0.5.0-alpha...HEAD
+[Unreleased]: https://github.com/ciphera-net/pulse/compare/v0.5.1-alpha...HEAD
+[0.5.1-alpha]: https://github.com/ciphera-net/pulse/compare/v0.5.0-alpha...v0.5.1-alpha
[0.5.0-alpha]: https://github.com/ciphera-net/pulse/compare/v0.4.0-alpha...v0.5.0-alpha
[0.4.0-alpha]: https://github.com/ciphera-net/pulse/compare/v0.3.0-alpha...v0.4.0-alpha
[0.3.0-alpha]: https://github.com/ciphera-net/pulse/compare/v0.2.0-alpha...v0.3.0-alpha
diff --git a/lib/utils/icons.tsx b/lib/utils/icons.tsx
index 3b71b46..7ec7742 100644
--- a/lib/utils/icons.tsx
+++ b/lib/utils/icons.tsx
@@ -15,7 +15,6 @@ import {
FaTabletAlt,
FaGoogle,
FaFacebook,
- FaTwitter,
FaLinkedin,
FaInstagram,
FaGithub,
@@ -24,6 +23,7 @@ import {
FaQuestion,
FaGlobe
} from 'react-icons/fa'
+import { FaXTwitter } from 'react-icons/fa6'
import { SiBrave } from 'react-icons/si'
import { MdDeviceUnknown, MdSmartphone, MdTabletMac, MdDesktopWindows } from 'react-icons/md'
@@ -67,7 +67,7 @@ export function getReferrerIcon(referrerName: string) {
const lower = referrerName.toLowerCase()
if (lower.includes('google')) return
if (lower.includes('facebook')) return
- if (lower.includes('twitter') || lower.includes('t.co') || lower.includes('x.com')) return
+ if (lower.includes('twitter') || lower.includes('t.co') || lower.includes('x.com')) return
if (lower.includes('linkedin')) return
if (lower.includes('instagram')) return
if (lower.includes('github')) return
@@ -183,6 +183,9 @@ export function mergeReferrersByDisplayName(
.sort((a, b) => b.pageviews - a.pageviews)
}
+/** Domains that always use the custom X icon instead of favicon (avoids legacy bird). */
+const REFERRER_USE_X_ICON = new Set(['t.co', 'x.com', 'twitter.com', 'www.twitter.com'])
+
/**
* Returns a favicon URL for the referrer's domain, or null for non-URL referrers
* (e.g. "Direct", "Unknown") so callers can show an icon fallback instead.
@@ -193,6 +196,7 @@ export function getReferrerFavicon(referrer: string): string | null {
if (REFERRER_NO_FAVICON.includes(normalized)) return null
try {
const url = new URL(referrer.startsWith('http') ? referrer : `https://${referrer}`)
+ if (REFERRER_USE_X_ICON.has(url.hostname.toLowerCase())) return null
return `https://www.google.com/s2/favicons?domain=${url.hostname}&sz=32`
} catch {
return null