Features (scroll, 404, outbound, downloads, frustration, storage, ttl)
are saved to site.script_features JSONB column on every toggle change.
Values are read from the site object on load.
handlePasswordSubmit now calls POST /public/sites/:id/auth which
sets an HttpOnly cookie. All subsequent API calls authenticate via
cookie automatically — no password in URLs, no captcha state needed
for data fetching. Simplifies share page state management.
Public dashboard endpoints use password auth, not session tokens.
A 401 on /public/ should surface to the caller (for password prompt),
not trigger a token refresh that fails and shows "Session expired".
Uses @icons-pack/react-simple-icons for available brands (Google,
Facebook, Instagram, GitHub, YouTube, Reddit, etc.) and inline SVGs
for brands missing from the package (X, LinkedIn, OpenAI, Bing).
All icons now show actual brand logos with correct colors.
Google's favicon service returns wrong/low-quality icons for known
services. Now all major platforms, search engines, and AI assistants
use their Phosphor icon directly. Favicons only fetched for unknown
domains.
Script detection now also searches by src URL and supports a global
config object (window.pulseConfig) for environments where data-*
attributes are not preserved on the injected script element.
Use real browser logos from alrra/browser-logos (SVG where available,
PNG fallback for archived browsers). Replaces the generic globe icon
with actual Chrome, Firefox, Safari, Edge, Opera, Brave, Vivaldi, Arc,
Samsung Internet, UC Browser, Yandex, Waterfox, Pale Moon, DuckDuckGo,
Maxthon, Silk, Puffin, Tor, and Opera Mini logos.
Add admin page at /admin/filtered-traffic showing domains blocked by the
referrer spam filter with reason badges and date range selector. Helps
operators monitor spam filtering and catch false positives.
Replace floating pill header with static variant for authenticated
views. Add collapsible sidebar with site picker, grouped navigation
(Analytics/Infrastructure), and mobile overlay drawer. Remove
horizontal SiteNav tab bar.
Remove Performance tab, PerformanceStats component, settings toggle,
Web Vitals observers from tracking script, and all related API types
and SWR hooks. Duration tracking is preserved.
Performance metrics moved from dashboard into a new Performance tab.
Fixed null handling so "No data" shows instead of misleading zeros.
Script no longer sends INP=0 when no interaction occurred.
Dashboard: compact Search Performance panel showing top 5 queries,
clicks, impressions, and avg position alongside Campaigns.
Search tab: clicks/impressions trend chart, top query position
tracker cards, and new queries badge.
SWR was retrying 429/401/403 responses with exponential backoff,
which cascaded into a flood of failed requests when the tab regained
focus. Now skips retries entirely for these status codes.
Search Console page with overview cards, top queries/pages tables,
and query↔page drill-down. Integrations tab in Settings for
connect/disconnect flow. New Search tab in site navigation.
All dates now use day-first ordering (14 Mar 2025) and 24-hour time
(14:30) via a single formatDate.ts module, replacing scattered inline
toLocaleDateString/toLocaleTimeString calls across 12 files.
Show the free tier (€0, 1 site, 5k pageviews, 6 months retention)
as the first card on the pricing page. Enforce a 1-site limit for
free plan users in the frontend.
Replace manual useState/useEffect fetch patterns with SWR hooks so
cached data renders instantly on tab revisit. Skeleton loading now
only appears on the initial cold load, not every navigation.
New hooks: useFunnels, useUptimeStatus, useGoals, useReportSchedules,
useSubscription — all with background revalidation.
Token refresh race condition: when multiple requests got 401 simultaneously,
queued retries reused stale headers and the initiator fell through without
throwing on retry failure. Now retries regenerate headers (fresh request ID
and CSRF token), and both retry failure and refresh failure throw explicitly.
SWR cache is now invalidated after token refresh so stale error responses
are not served from cache.
Remove the individual session journey page and make the live visitor
count a static indicator. Prepares for the new aggregated User Journeys
feature (v0.17).
Replaces 4 separate frustration API calls with single useBehavior hook.
Removes manual fetchData, loading/error state, and refresh interval—SWR
handles caching, revalidation, and error state automatically.
Add send hour, day of week/month selectors to report schedule modal.
Schedule cards now show descriptive delivery times like
"Every Monday at 9:00 AM (UTC)". Timezone picker moved into modal.
Plain name referrers like "Instagram" or "WhatsApp" (inferred from
User-Agent) were being passed to the favicon service as invalid
domains, returning a generic globe. Now skips favicon fetch for
any referrer without a dot, falling through to Phosphor icons.
Add LRU cache provider (200 entries) to prevent unbounded SWR memory
growth. Clean up stale PKCE localStorage keys on app init. Cap chart
annotations to 20 visible reference lines with overflow indicator.
Replace 5-second setInterval polling with EventSource connection to the
new /realtime/stream SSE endpoint. The server pushes visitor updates
instead of each client independently polling. Auto-reconnects on
connection drops.
Replace useDashboardOverview, useDashboardPages, useDashboardLocations,
useDashboardDevices, useDashboardReferrers, useDashboardPerformance, and
useDashboardGoals with a single useDashboard hook that calls the existing
/dashboard batch endpoint. This endpoint runs all queries in parallel on
the backend and caches the result in Redis (30s TTL).
Reduces dashboard requests from 12 to 6 per refresh cycle (50% reduction).
At 1,000 concurrent users: ~6,000 req/min instead of 12,000.
Swap the main site dashboard chart from a bar chart to a line chart
using 21st.dev's line-charts-6 component with dot grid background,
glow shadow, and animated active dots. Add Badge trend indicators
on metric cards using Phosphor icons. All existing features preserved
(annotations, comparison, export, live indicator, interval controls).
New UI primitives: line-charts-6, badge-2, card, button-1, avatar.
Added shadcn-compatible CSS variables and Tailwind color mappings.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Custom calendar (DatePicker) instead of native date input
- Custom dropdown (Select) instead of native select
- EU date format (DD/MM/YYYY) in tooltips and form
- Right-click context menu on chart to add annotations
- Optional time field (HH:MM) for precise timestamps
- Escape key to dismiss, loading state on save
- Bump @ciphera-net/ui to 0.0.95
Adds toggle in Data & Privacy > Filtering section to exclude entries
where geographic data could not be resolved from location stats.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace react-icons and @radix-ui/react-icons with @phosphor-icons/react
for a consistent icon style across all dashboard panels.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
window.location.reload() causes infinite loops when the CDN keeps
serving cached assets. Instead, silently treat Server Action failures
as no-session — the OAuth flow uses full navigations (window.location.href)
which naturally fetch fresh content from the server on return.