Changelog

What's new

Every release, with dates and detail. Shipped continuously — pull this page, the GitHub repo, or the RSS feed for the freshest version.

Latest release · June 15, 2026 · v2.13.0

Cobalt everywhere — emails, sign-in, badges, a denser layout

The cobalt refresh now reaches every corner: transactional emails, the browser/PWA theme color, embeddable badges, the sign-in screen, and the error page all match the new look (semantic greens for “good/healthy” were kept green on purpose).

See full notes
Improvedv2.13.0

Cobalt everywhere — emails, sign-in, badges, a denser layout

  • The cobalt refresh now reaches every corner: transactional emails, the browser/PWA theme color, embeddable badges, the sign-in screen, and the error page all match the new look (semantic greens for “good/healthy” were kept green on purpose).
  • The dashboard is a touch denser — tighter card padding, spacing, and row heights — so you see more at a glance.
Improvedv2.12.2

Site Audit — scan and inspect

  • The Site Audit's findings are now a scannable signal-row list — a severity dot, the finding, and how many pages it affects. Click any one to read the full detail, the fix, and the affected pages in a side panel — the same fast pattern as the Action Queue and Chats.
Improvedv2.12.1

Chats — scan and inspect, too

  • The Chats timeline now uses the same fast pattern as the Action Queue: each AI answer is a scannable row with a clear “Mentioned” signal, and clicking it opens the full answer + the brands it named in a side panel.
Improvedv2.12.0

Action Queue, reimagined — scan and inspect

  • The Action Queue is now a dense, scannable list: each recommendation is a single row with a priority status dot, type, and value — far faster to triage at a glance.
  • Click any row and its full detail opens in a panel right beside the list, instead of loading a separate page — review and act (Accept · Done · Snooze · Dismiss) without ever losing your place.
Improvedv2.11.2

Signal colors — AI in purple, live in cyan

  • Color now carries meaning consistently: AI / generative surfaces read in purple, and live / realtime indicators in cyan — so you can tell signal types apart at a glance.
Improvedv2.11.1

Dark by default + cooler surfaces

  • PerchLens now opens in dark mode by default, matching the refreshed look. You can still switch to light anytime from the theme toggle — your choice is remembered.
  • Surfaces moved to a cooler, more technical gray for a calmer, more focused workspace.
Improvedv2.11.0

A sharper new look — cobalt, Geist, crisp edges

  • PerchLens has a fresh visual identity: a confident cobalt-blue accent in place of emerald, the clean Geist typeface across the whole product, and crisper near-square corners. This is the first step of a broader design refresh rolling out over the next releases.
  • Trend arrows now read green for up and red for down independently of the accent color, so direction is never ambiguous.
Improvedv2.10.1

Geography map + tidier dashboard order

  • The dashboard now flows in a more useful order: Busy times sits right under your traffic trend, with Geography directly below it.
  • Geography (on the dashboard and the Globe page) now draws a lightweight 2D world map of where your visitors are — a dot per country sized by visits, hover for the count. Rebuilt as pure SVG after the earlier map/globe libraries proved unreliable.
  • Realtime: the visitor stream now shows proper country flags instead of raw country codes.
Newv2.10.0

See your visitors on a globe

  • New Globe page (Analytics → Globe): a live, rotating 3D globe of where your visitors are right now, with a glowing marker on every country sized by its sessions. Drag to spin it.
  • Prefer flat? One click switches to a 2D world map shaded by sessions, with hover tooltips per country.
  • A live Sessions panel shows visitors as they arrive — country, page, and source — and a Top countries rail ranks your geography at a glance.
  • Everything is real, period-aware data — no sample points. Falls back to the 2D map automatically on devices without WebGL.
Improvedv2.9.0

Two clear products, one switch — Analytics and AI Visibility

  • Your dashboard is now two focused products under one login. A switch at the top of the sidebar flips between Analytics (your website traffic) and AI Visibility (your GEO / search + AI-answer optimization) — each with its own short, single-purpose menu instead of one long mixed list.
  • The AI Visibility side groups everything in one place: the AI-engine overview, tracked prompts, the Action Queue, competitors, SEO, and reports.
  • Nothing was removed — it's just organized so neither product buries the other, and each menu stays short and clear.
Improvedv2.8.0

Dashboard flows as one scroll; AI insights unified; live busy-time marker

  • Your site dashboard is now one natural scroll — we removed the Overview / Audience / Acquisition / Engagement / AI tabs, which were showing overlapping copies of the same cards. Everything that matters is on one page, most decisive first.
  • Top Pages and Top Sources now link straight into their full pages (“See all →”) — the dashboard gives you the highlights, the dedicated pages give you the depth.
  • AI, unified: the engine-by-engine deep-dive now lives on the AI Visibility page as a “By engine” tab (it used to be a hidden, unreachable page). One home for everything AI.
  • The Busy times chart now marks the current hour, so you can tell at a glance whether right now is a busy time.
  • Cleaner empty states on new sites, and the realtime “requires Pro” note is now a one-click upgrade link.
Improvedv2.7.0

A calmer, tidier dashboard — one top bar, clearer navigation

  • Redesigned the dashboard chrome: a single slim top bar on every page with a breadcrumb (where you are) and one global date-range filter — replacing the old stacked headers, so pages open straight into your data.
  • New date filter in the top bar — switch Today / 7 days / 30 days / 3, 6, or 12 months from one place, on any page.
  • Reorganized the sidebar into clear groups — Analytics, Visibility, and Workspace — so every page has an obvious home.
  • Brought the Visibility pages (Action Queue, SEO, AI Visibility and more) in line with the rest of the app for one consistent, calmer design language.
  • Lighter and faster under the hood — removed a large amount of dead code and a duplicate page.
Improvedv2.6.0

Dashboard, reimagined — most important first, daily by default, new long ranges

  • Your main dashboard now opens on Daily by default when you pick a site, with a new range switcher: Day, Week, Month, plus 3-, 6-, and 12-month views.
  • Reprioritized so the most important things come first — headline KPIs and your traffic trend, then AI visibility (which engines are sending you visitors) alongside your top SEO/GEO fixes, then a plain-English 'what changed' summary, then who's on the site right now.
  • Top fixes: the three highest-priority open recommendations from your Action Queue now surface right on the dashboard, one click from the full queue.
  • Live signals: a 'now' indicator on Visitors plus a live per-minute pulse, so the numbers feel as current as your traffic.
  • Built lean — it reuses your existing analytics and AI summaries (cached so it stays near-free) and keeps every label honest.
Fixedv2.5.1

Add-site flow, real-time, and shared dashboards — wired end to end

  • Adding a site now works end to end — the setup wizard creates your site, gives you the install snippet with your real tracking ID, and watches live for your first event.
  • Real-time now shows true last 1m / 5m / 30m visitor counts and a live per-minute pulse, derived from your actual event stream.
  • Shared (public) dashboards now render the traffic-over-time chart, real period-over-period deltas, and KPI sparklines instead of blank placeholders.
  • AI traffic band shows a real week-over-week change; the per-engine figure is hidden where there isn't enough history to compute it honestly.
  • Heatmaps: real device segmentation (desktop / mobile / tablet) from click data, a real page picker, and honest 'coming soon' states for movement / scroll / rage.
  • Tidied a couple of presentational placeholders — removed a non-functional heatmap time slider and corrected the Sites workspace label.
Newv2.5.0

Wiki — the PerchLens knowledge base in copyable Markdown

  • New public Wiki at /wiki — the complete PerchLens knowledge base (overview, getting started, analytics, AI traffic & GEO, the Action Queue, integrations, privacy, plans, FAQ, and a glossary) in clean, structured Markdown.
  • Built for the AI era: copy any section as Markdown, copy the entire wiki in one click, or download it as a single file. Fetch it directly at /wiki.md (curl-friendly) to feed into any AI assistant as grounding context.
  • TechArticle structured data + sitemap inclusion so the knowledge base is itself GEO-friendly — practicing what PerchLens preaches.
Improvedv2.4.1

Settings jump-nav + dashboard consistency polish

  • Settings now has a sticky section nav — jump straight to Tracking, Reports, Notifications, Integrations, Sharing, Filters, or Danger Zone instead of scrolling the whole page
  • Normalized vertical spacing across dashboard pages so the rhythm is consistent (Search & SEO and the Visibility hub now match their siblings)
  • Faster, leaner landing page — trimmed unused component CSS (~190 KB), scoped the auth + support bundles to the pages that need them, and stopped a background canvas from over-rendering on long pages
Newv2.4.0

AI action quota, AppSumo lifetime tiers, IA refresh, pricing redesign

  • Monthly AI action quota — Pro 100 / Studio 500 / Free 0. Each Ask AI, Action Queue Generate, GEO refresh, topic regenerate, prompt run, or anomaly Explain consumes one action. Resets on the 1st of every month. Live counter + progress bar live in Settings.
  • AppSumo lifetime tier scaffolding (stackable T1 / T2 / T3, best-tier-wins). Schema, redemption flow, and LTD-aware AI quotas all wired through; activation gated on actual deal launch.
  • New /appsumo landing page — three lifetime tier cards, stacking explainer, AI-action explainer, FAQ. Linked from the marketing footer and the /pricing trust strip.
  • Sidebar IA cleanup — trimmed from 17 entries to 10. Demoted destinations (Integrations, Heatmaps, Compare, Visibility sub-pages) stay reachable via contextual cross-link strips on their parent pages, the new /visibility hub, the command palette, and the mobile More menu.
  • Visibility hub at /visibility — summary tiles + quick-link cards to Action Queue, Topics, Competitors, GEO Tracker, Reports, and Setup. Setup form moved to Settings.
  • /pricing redesign — solid brand pill replaces the gradient on the featured card, honest CTAs (Start free / Get Pro / Get Studio), per-card audience eyebrows, grouped comparison table (Capacity / Analytics / AI / Workflow), new trust strip + AI-action explainer.
  • /roadmap surfaced as a credible public commitment — 21 seeded items across shipped, in-progress, planned, and proposed buckets, aligned to the actual changelog.
  • /vs/* comparison pages updated with the new Visibility action queue as a top-of-table feature row.
  • Backend-leak copy scrubbed across Settings and Visibility surfaces (no more "Drizzle", "deterministic pass", "configured LLM", specific anomaly thresholds, or internal plan slugs in user-facing text).
  • Density pass across the Visibility section — tighter paddings, list-row heights, and section gaps for a Linear-style read.
  • Action Queue URL filters — ?priority= and ?status= now apply on mount; selections survive refresh and copy-paste.
  • Inline two-step confirm replaces window.confirm() on destructive row actions (Competitors, GEO prompts).
  • Status display polished — title-cased status badges on the recommendation detail card; tab-aware counts on the Action Queue header.
Newv2.3.0

Visibility — persisted SEO + GEO action queue, topic clusters, competitor tracking, weekly reports

  • New Visibility section in the sidebar with Overview, Action Queue, Topics, Competitors, GEO Tracker, and Reports routes
  • Persisted, prioritized recommendations with status management (new, accepted, in_progress, done, dismissed, snoozed) — your triage survives every regenerate
  • Recommendation generator combines a deterministic pass over your latest crawl with an AI pass over your niche, top pages, GSC queries, and competitor topics
  • Topic clusters detected from the latest crawl and named via AI; pillar + supporting + missing-page suggestions per cluster
  • Competitor tracker (Pro 5, Business 20) with light-fetch topic detection and gap surfacing into the action queue
  • GEO prompt tracker — seed 10–20 niche-derived prompts and run heuristic visibility estimates against tracked competitors
  • Weekly visibility reports — counts of new / done / dismissed plus the top 5 high-priority open items
  • Engine reuses the existing crawler, AI provider chain, GSC integration, and analytics infrastructure — no new heavy dependencies
Fixedv2.2.5

Second audit pass — heading hierarchy, semantic sites table, unified headers

  • Pricing section on the marketing home page uses h2 so the hero keeps the only h1
  • Sites hub desktop view is a semantic table with proper column headers
  • GEO, SEO, and Heatmaps use DashboardHeader; page titles visible on all screen sizes
  • Remaining dashboard insight modules lazy-load; StatCard and MetricRow memoized
Fixedv2.2.4

Audit fixes — accessibility, touch targets, and bundle splitting

  • Command palette search input and pricing comparison table are fully accessible (labels, semantic table, document h1)
  • Sites sort controls, audit accordions, and decorative icons use correct ARIA patterns
  • Mobile tap targets normalized with tap-44 on toast dismiss, map zoom, and site delete actions
  • Dashboard, Settings, and GEO routes lazy-load heavy analytics sections to reduce initial bundle weight
Improvedv2.2.3

Finish deferred dashboard UX — proxy migration, insights dismiss, empty states

  • Migrated Clerk auth from middleware.ts to proxy.ts (Next.js 16 convention — removes build deprecation warning)
  • Insights strip can be dismissed for the day; Content health panels collapse on Dashboard and Pages
  • EmptyState coverage extended to Pages, Sources, Settings (API keys, team), Conversions, and Integrations load errors
  • Audience tab always shows Cities and Languages cells with proper empty states
  • Instant loading skeletons on AI traffic, Migrate, and Upgrade routes
Improvedv2.2.2

Dashboard polish — faster load, clearer mobile nav, less clutter

  • Collapsible Insights strip groups anomaly alerts, first-run insight, and AI narration — collapse preference is remembered
  • Acquisition and Engagement tabs tuck Search Console, conversions, journeys, and Web Vitals into expandable Advanced sections (collapsed by default)
  • Main dashboard shows the header and date filter immediately while analytics data loads
  • Mobile top bar labels the command palette Search; Sites hub and Compare use All Sites in the breadcrumb
  • Dashboard page titles hide on small screens when the topbar already shows the same context
  • Instant loading skeletons on GEO, SEO, Heatmaps, and Sites routes
  • Consistent EmptyState messaging across dashboard, GEO, SEO, heatmaps, GSC keywords, Web Vitals, and AI crawlers
Fixedv2.2.1

Security and reliability fixes for analytics and share dashboards

  • Analytics batch and public share routes now fail closed when the app database is unavailable, matching the main analytics API and closing IDOR and gate-bypass edge cases
  • Password-gated share dashboards use opaque signed session cookies instead of storing the password hash in the browser cookie
  • Generic annotation webhooks now require Authorization: Bearer only (query-string tokens removed)
  • Analytics API failures return proper HTTP error codes; dashboard hooks surface errors instead of silently showing empty data
  • Team invites send email when Resend is configured
Improvedv2.2.0

Hardening pass — accurate numbers, manageable events, a cleaner dashboard

  • Pinned chart events are now fully manageable — click any event chip to edit its label, date, or notes, or remove it behind a two-step inline confirm. Pinning used to be one-way: a typo'd label was permanent and clearing an event meant a raw API call. The Pin-event dialog also picked up a layout fix — on desktop its header, form, and actions had been rendering as three squashed columns
  • Conversions now count what they should — behavioural events were being miscounted as conversions, and element-click and custom-event goal progress weren't being counted at all. Both are corrected, and several dashboard metrics that showed placeholder or wrongly-computed values now reflect real data
  • GEO and SEO recommendations are downloadable — take the full list out of the dashboard to share with a teammate or work through offline
  • Delete a site you no longer track straight from the sites list, instead of leaving it orphaned in the switcher
  • Adding a site is more reliable: a missing production migration that had been breaking site creation outright is applied, the form now surfaces the real error when something fails instead of a generic message, and the www and non-www versions of a domain are treated as one site rather than two
  • The onboarding wizard reliably restores its place if you reload mid-setup, and the "verify your tracking snippet" check polls more dependably
  • An accessibility and visual-consistency sweep across the dashboard — contrast ratios, keyboard focus indicators, ARIA labelling, and consistent design-token usage so light and dark modes stay coherent
  • Fixed a dashboard view that could crash on certain renders — a React hook was running conditionally — and added a build-time ESLint guard so that whole class of bug can't ship again
  • An end-to-end bug hunt closed a date-boundary case that could double-count a day of traffic, an auth check that failed open, and two API routes that could return a 500 on malformed input
  • Under the hood: dropped six unused dependencies and removed dead starter-kit files, scoped a cron query that had been loading an entire table on every run, and extended the schema-drift checker to cover more tables
Newv2.1.0

Annotation auto-imports — release tags + deploys land on every chart automatically

  • GitHub Releases webhook: paste your perchlens annotation URL into any repo's webhook settings and every published release becomes a labelled vertical line on every chart on the site. Tag-named, described with the release title, drops within seconds of `gh release create`
  • Vercel deploys webhook: same idea, for production deploys. "Deploy · main" lines tag every successful production deploy, described with the first line of the commit message. Preview deploys and errored deploys are ignored — only the events worth marking get marked
  • Generic webhook: POST JSON to your site's annotation URL with a bearer token and we'll create the annotation. Body is `{ label, description?, occurredAt?, externalRef? }` — wire Zapier, cron, CI, or anything that can POST. The Twitter campaign launch at 9am Tuesday is one curl away
  • New Settings → Integrations panel — one shared per-site webhook secret, three copyable URLs, brief setup steps inline for each integration, and a rotate-secret button with two-step confirmation. The secret is masked by default so screenshotting the panel doesn't leak it
  • Pinned-events chip strip now shows source affordance: small Pin icon for events you pinned manually (brand emerald), small GitBranch icon for GitHub releases (muted), Rocket for Vercel deploys (muted), Lightning for generic webhooks (muted). Tooltip on each chip leads with the source label so screen readers + hover both get the context
  • Mobile bottom sheet: "How AI traffic is detected" modal now renders as a Vaul drag-to-dismiss bottom sheet on phones, joining Pin event and Add conversion. Last centred modal in the dashboard cleared
  • Monthly digest emails get their own template — subject becomes "<Month> in review — <site>" instead of the weekly-looking "Weekly · …" prefix that the shared template was producing; eyebrow and CTA copy are also monthly-framed. The data shape and the editorial typography pass from Day 25 are unchanged
  • Under the hood: shared HMAC-SHA256 / HMAC-SHA1 / bearer-token verifiers in src/lib/webhook-secret.ts with constant-time comparison; raw-body reading on all three webhook routes (re-parsing JSON would break signatures); dedup by externalRef so idempotent retries from GitHub/Vercel update in place instead of duplicating
Launchv2.0.0

The AI Era release — a dashboard that narrates itself

  • GEO recommendations now stream — the page no longer sits on a 30-second "thinking…" spinner; each recommendation card renders as the model emits it, line by line, so you see the first idea before the third one finishes generating
  • Every analytics surface (Overview, Realtime, Sources, Pages, GEO) now opens with a one-paragraph narration that streams in — "Mobile share jumped 11pts this week; ChatGPT referrals doubled; your /pricing page lost 8% of converts." Reads the data, finds the story, says it plainly. New <InsightBanner surface="…"/> primitive — one prop swaps the voice per page
  • Anomaly banners gain an "Explain" button that streams a Claude-narrated likely cause in plain English — pulls today's vs yesterday's top pages as context, returns a 60-word paragraph, rate-limited 10/hour per user
  • Cmd+K (or just "/") now streams the answer to whatever you ask about your data — tokens render as they arrive instead of waiting for the full reply. Suggested follow-up questions appear under each answer, and your last 6 questions persist across sessions
  • Weekly + monthly email reports now lead with your single highest-impact GEO recommendation — pulled from the cache the streaming endpoint already warms, so emails stay free and fast. If you haven't opened /geo this week the block omits silently
  • Anomaly alerts now route by severity: spikes go to webhook only (Slack/Discord), drops email + webhook, critical drops (≥95% collapse) get a 🚨 URGENT prefix and red Block Kit color. The Severity field lands in every payload for downstream filtering
  • Editorial typography pass on email reports — Georgia serif headings, tighter measure, soft 4%-shadow metric cards instead of hard borders, warmer cream background. Same data, reads like a Monocle column instead of a status email
  • Date filters are now URL-synced (?from=2026-01-01&to=2026-01-31&range=Q1+2026) — "save view" is now just "bookmark this URL." Paste a URL into Slack to share the exact dashboard state; no backend table, no extra storage
  • Plus: provider-agnostic streamClaude() under the hood streams across OpenRouter → DeepSeek → Anthropic with the same fallback chain as single-shot calls, so a $0.0003 GEO run still costs $0.0003 streaming; SUGGESTIONS= tail-buffering hides control markers from the streamed answer mid-flight; cache hits replay as synthetic streams so cached and live render identically
  • Why v2: this is the AI Era release — the first version where the dashboard talks back. Everything else is groundwork.
Newv1.9.0

Sprint 1 — Clear the deck

  • Canonical <EmptyState> primitive — every "No data yet" / "No goals yet" / "No sites match" screen now speaks the same voice, with a brand→accent halo behind the icon, tooltips on long labels, and proper CTAs where they belong
  • First-goal flow on /conversions now surfaces the goal suggestions scraped from your site during onboarding — "Track visits to /pricing" instead of generic templates
  • Tier rename: Business → Studio. Pro/Studio is more distinctive than the Plausible-tier "Pro/Business" cliché; a future Agency tier is architected in the schema as released:false so we can ship it later without a rebuild
  • Universal site importer at /migrate — paste a list of domains (or CSV with domain,name headers) and we create matching PerchLens sites in one shot, deduped, plan-limit-aware, partial-success-friendly
  • Beam Analytics sunset (Sep 1, 2026) gets a migration banner above the standard /vs/beam comparison with a CTA into the importer pre-filled for that source
  • Live-visitors widget now streams via Server-Sent Events instead of polling every 2 minutes — sub-5-second freshness on the active count + recent events feed for Pro+, with a graceful single-pulse close on free so the upgrade is felt
  • Chart annotations: pin events ("v2.0 launch", "Twitter post", "press hit") to a date and render them as labelled lines on every chart on that site. New endpoint, hook, modal, pinned-events strip on /all-in-one. Schema supports four ingestion sources (user-pinned, GitHub Releases, Vercel deploys, generic webhook) — auto-imports next sprint
  • ResponsiveDialog primitive — modals now render as native-feeling bottom sheets on phones (Vaul, with grab handle + drag-to-dismiss + safe-area-aware padding) and the existing centred dialog on tablet+. Pin event + Add conversion are the first two surfaces migrated
  • Plus: middleware allowlists the new /migrate route; <ReferenceLine> support added to TrendChart so any future chart inherits annotation rendering for free
Newv1.8.1

TinyTalk support widget on every page

  • Floating chat bubble loads on every page (marketing + dashboard) right after hydration — never competes with first paint
  • Single bubble in the bottom-right is the universal entry point — same on the landing page and inside the dashboard
  • Powered by TinyTalk; previous AnyChat integration removed (its dashboard menu wasn't reliably configurable)
Newv1.8.0

New brand mark + PWA install everywhere

  • New emerald PerchLens brand mark (an eye motif inside the 'P') replaces the placeholder squircle across favicon, apple touch icon, OG image, footer, in-app logo, and email reports
  • Full PWA install support: manifest now ships any-purpose + maskable icon variants in 192/512/180 — meets Chrome and Android installability spec
  • PWA install nudge: subtle bottom-right banner appears 8 seconds after dashboard mount on supported browsers; prompts native install on Chrome/Edge/Brave/Samsung, shows iOS Add-to-Home-Screen instructions on Safari, dismissible and remembered
  • Dropped Lobster Two font (only used by deleted Satori OG generators) — saves ~235KB from the build and one fewer Google Fonts request on first load
  • Email-report header now uses the real brand mark image instead of the inline 'PL' placeholder
Fixedv1.7.6

A11y: focus-visible on the last 9 unfocused buttons

  • Added focus-visible outlines to onboarding-wizard close, onboarding-banner dismiss, section-error retry, zoomable-map reset zoom, landing FAQ accordion, and four buttons in site-audit-section (toggle, insight filter, load past results, schedule frequency)
  • These had escaped earlier audit passes because they had no focus styling at all (not even a base focus: pseudo-class) — the deeper grep this round caught them
  • Resolves the last WCAG 2.4.7 Level AA gaps in the dashboard and marketing surfaces
Fixedv1.7.5

Security: explicit deny-all RLS policy on cv_events

  • Resolves Supabase Advisor INFO warning rls_enabled_no_policy on cv_events
  • Adds a RESTRICTIVE policy that denies all anon + authenticated access — functionally identical to the empty policy set we had before, but the linter now sees a policy exists and future maintainers get a clear signal that the design is intentional
  • Service role (ingest) and SECURITY DEFINER functions (analytics_query, ai_trend_query) continue to bypass RLS — no functional change for the app
Fixedv1.7.4

Security: revoke public access to SECURITY DEFINER analytics functions

  • Resolves two Supabase Advisor warnings (anon_security_definer_function_executable + authenticated_security_definer_function_executable) on analytics_query and ai_trend_query
  • REVOKE EXECUTE from anon and authenticated roles on both functions
  • Service-role calls (every legitimate path through our app) keep working — they bypass GRANT/REVOKE entirely
  • External /rest/v1/rpc/analytics_query and /rest/v1/rpc/ai_trend_query calls with the public key now correctly return 403
Improvedv1.7.3

Third audit pass — broad tap-target sweep, theming, polish

  • Extended tap-44 mobile hit-area utility to ~16 more icon buttons across pages, sources, realtime, geo, sites, settings, anomaly banner, first-insight banner, web vitals, usage bar, theme toggle, toast, site audit, and onboarding wizard
  • All 3 decorative imgs in empty-state get loading="lazy" (was 1 of 3)
  • Textarea resize-handle hex extracted to named constants (RESIZE_HANDLE_LIGHT/DARK) with explicit comment explaining why CSS vars can't expand inside SVG data URLs
  • Documented the tap-44 pattern in globals.css with a usage example so new icon buttons stay in compliance
  • Removed dead fade-in-up keyframe + animate-page-enter utility (PageTransition uses motion/react, the CSS fallback was scaffolded but never wired)
Fixedv1.7.2

Security: enable RLS on every public Supabase table

  • Resolves both Supabase Advisor critical alerts (rls_disabled_in_public + sensitive_columns_exposed)
  • New migration 20260501000000_enable_rls_all_public.sql sweeps every public table and enables RLS — covers cv_events plus any tables added since the v1.6.x cv_events fix
  • No new policies required: app traffic uses service_role (bypasses RLS) for ingest and SECURITY DEFINER functions (analytics_query, ai_trend_query) for reads; both bypass RLS by design
  • Cleanup: deleted a misplaced Neon migration (webhooks_anomaly.sql) that had been wrongly placed in the Supabase folder and was failing every push
Improvedv1.7.1

Second audit pass — bundle splitting, tap targets, lazy images

  • CommandPalette + ShortcutsModal now dynamic-import — defers ~40KB of Cmd+K and shortcuts UI for the 90% of dashboard visits that never trigger them
  • Settings live-visitor-badge image gets loading="lazy" — was the last below-the-fold img missing it
  • Extended tap-44 mobile hit-area utility to icon buttons across the dashboard topbar, AI detection modal, command palette, onboarding banner, and theme toggle
  • Landing header drops backdrop-blur for solid bg-primary — quieter, more honest, matches the brand voice
Improvedv1.7.0

Audit pass — accessibility, theming, performance polish

  • Removed banned left-stripe border from blog blockquotes — replaced with a leading quote glyph
  • Stripped templated FeaturedIcon-above-heading pattern from landing feature grid; small inline brand icons now sit beside the title
  • Added focus-visible to the last few bare buttons in the command palette and cost estimator
  • Tokenized heatmap palette: red/amber/emerald oklch instead of the off-brand cyan
  • Chart tooltip now uses fg-white token; GEO unknown-engine fallback uses brand-emerald instead of generic indigo
  • Mobile tap targets: dashboard icon-only buttons (delete/edit/dismiss) get a 44×44 hit area on small screens via a new tap-44 utility
  • Lazy-loaded below-the-fold images on docs/badges and empty-state
  • OnboardingWizard now dynamic-imports — keeps the dashboard's main bundle lean for the 95% of users who don't see it
  • Mobile bottom nav drops backdrop-blur for plain solid background — quieter, more honest
  • Cleanup: removed 5 dead landing/component files and 11 stale lifetimeDeal data rows
Newv1.6.0

Paddle checkout live, richer dark theme, mobile home, header theme toggle

  • Paddle checkout wired up — Pro ($9/mo) and Business ($29/mo) plans are purchasable from /upgrade
  • Webhook endpoint at /api/webhooks/paddle handles subscription.created / activated / updated / canceled events with signature verification and replay-protection
  • Plan changes from Paddle automatically update sites.plan in the database via custom_data.siteId
  • Dark theme refreshed: deeper background, wider lightness spread between layers (cards now visibly lift), subtle emerald tint replaces the flat gray feel
  • Theme toggle (sun/moon) added to the marketing header — visible on every page in both desktop and mobile
  • Mobile bottom nav: 'Sites' added as the leftmost tab so you can always get back to all-sites view (Heatmaps Beta dropped to make room)
Improvedv1.5.0

Pricing simplified, Paddle checkout prep, landing color pass

  • Pro plan price set to $9/mo (down from $12)
  • Lifetime tier removed for now — focusing on the recurring plans
  • New public /pricing page with full plan comparison and Product schema
  • nxyz named as the operating legal entity in Terms of Service
  • Hero 'AI era' headline now uses direct emerald so it's unmistakably brand-colored in dark mode
  • Section kicker labels (Features, Pricing, AI Attribution, FAQ, Ask AI) all switched to bright emerald in dark mode
  • Pro pricing card gets a hero-glow halo, gradient brand→accent Most Popular badge, and shadow-hero CTA
  • CTA section: middle quote gets a coral pip; primary button gets shadow-hero
  • Nav links #features and #pricing now route absolute (/#features, /#pricing) so they work from /changelog, /blog, etc.
Newv1.4.0

Blog + Display preferences + dashboard polish pass

  • New blog at /blog with MDX, RSS feed, per-post Open Graph images, and Article schema for AI search engines
  • First post: 'Welcome to PerchLens'
  • Display preferences in Settings: per-browser timezone picker (curated 70-zone IANA list) — Busy Times now respects your chosen timezone
  • Busy Times: accent ring + breathing pulse on the current day/hour cell, target icon next to peak time, TZ chip linkable to settings
  • Date filter shows a coral pip when range differs from the default 'Last 7 days'
  • Toast notifications get a soft animated halo on success and error icons
  • Anomaly banner gets a subtle hero-glow aura to draw the eye
  • Sample data badge gently pulses to signal you're not on real data yet
  • Recent events row hover lift + animate-ping dot on the most-recent event
  • Sidebar and mobile nav: active items get a small accent dot indicator
Improvedv1.3.0

Loading shimmer, compact numbers, achievement state

  • Skeleton loaders now use a real shimmer wave (replacing the plain pulse)
  • Secondary stat cards format large numbers compactly: 12,345 → 12K, 1,234,567 → 1.2M
  • Conversion rows celebrate when the target is hit — soft success border, ✓ Hit badge, gentle progress-bar pulse
  • Sidebar active items get a brand-tinted icon and small accent dot for a clearer 'you are here' cue
Newv1.2.0

Coral accent palette + flashy hero treatments

  • Introduced a warm coral accent (--color-accent-*) for hero moments, leader/heat semantics, and 'look here' emphasis
  • Hero metrics now have a soft brand→accent radial halo, animated number counter, and staggered sparkline reveal
  • Sparklines on stat cards: gradient fill underneath, draw-on animation on mount, hover lift on the parent card
  • Bar lists now stagger-rise from zero on mount; the leader gets the new accent tint
  • Empty states get a brand→coral halo behind the icon and warmer copy
  • Primary CTAs can opt into a soft brand glow via a new shadow-hero utility
  • All animations respect prefers-reduced-motion
Newv1.1.0

Conversions overhaul + tracking script v2 + site-wide tooltips

  • Conversions page rebuilt: unified list (replacing the split goals/conversions view), inline edit, 8 preset templates, multi-step create dialog with autocomplete and live code snippets
  • Conversion 'Resets' toggle: choose monthly reset or running total per goal
  • Tracking script v2.0: data-track attribute click tracking, automatic form_submit detection, scroll-depth events at 25/50/75/90%, file-download detection (pdf/zip/docx/etc.), and copy event with character length only
  • MetricRow and StatCard now accept a tip prop that renders an inline help tooltip — wired across the all-in-one dashboard
  • Always-visible explainer strip on the Conversions page so beginners understand what conversions are
Improvedv1.0.0

Audit fixes — accessibility, performance, font, typography

  • Body font swapped from Inter to Geist for better on-screen readability
  • WCAG 2.4.7 focus-visible outlines added to every bare button across the dashboard
  • Replaced transition-all with property-specific transitions to eliminate unnecessary style recalculations
  • motion-safe: prefix on key dashboard animations to honor prefers-reduced-motion
  • BentoStat 'Visitors' tile gains visual hierarchy as the hero metric (larger size, primary weight)
Newv0.9.0

AI insights, bot filtering, daily digest, live demo

  • AI Insight card on Overview: natural-language summary of your traffic trends
  • Bot filtering: Googlebot, Bingbot, and 15+ crawlers excluded from analytics
  • AI referral detection: ChatGPT, Perplexity, Claude, Gemini, Copilot traffic tracked
  • Page title capture: dashboard shows page titles alongside paths
  • Date comparison: metric cards show % change vs previous period
  • Daily digest email with anomaly detection (spike/drop alerts)
  • Live demo on landing page: real dashboard, no signup required
  • Public dashboard customization: custom title and description
Newv0.8.3

Animated background + enhanced world map

  • Floating gradient orbs background on landing page and dashboard
  • Subtle intensity for dashboard, full effect on marketing site
  • Works in both light and dark themes via opacity modulation
  • World map: country list with rank, ISO code, and hover percentage
  • All analytics queries migrated to Supabase RPC — zero cold starts
Improvedv0.8.1

Data honesty, docs, and polish

  • Date range picker now filters all dashboard data
  • Web Vitals shows upgrade prompt for free users
  • Removed fake metrics (bounce rate, conversion rate, avg time)
  • Goals documented in /docs with API examples
  • Loading skeletons replace blank screens
  • Updated marketing copy to match actual features
Newv0.8.0

Redis cache, OS tracking, trust signals

  • Date range picker now filters all dashboard data
  • Upstash Redis distributed cache for faster page loads
  • Operating system detection (Windows, macOS, iOS, Android, Linux)
  • UTM campaign dashboard on Sources page
  • Loading skeletons instead of blank screens
Newv0.7.0

Web Vitals, Goals, Team Members

  • Web Vitals tracking (LCP, CLS, FID) — Pro only
  • Goals with progress bars on Conversions page — Pro only
  • Team member invites with role management — Pro only
  • Collapsible sidebar (icon-only on medium screens)
  • Bigger site cards with 4 metrics and activity bar
Improvedv0.6.0

API optimization & security hardening

  • Batch API reduces 6 HTTP calls to 1
  • Server-side analytics cache (5min standard, 15s realtime) via Upstash Redis
  • Realtime auto-refresh is now Pro-only
  • Plan limits enforced: Free 3 sites/10K PV, Pro 25 sites/100K PV
  • Security: plan field removed from PATCH, settings whitelist, input validation
Newv0.5.0

Multi-site support & analytics pipeline

  • Add and manage multiple websites from a single dashboard
  • Site selector dropdown in the sidebar for quick switching
  • Supabase analytics pipeline for real-time event ingestion
  • Lightweight tracking script (cv.js v1.4) with SPA + Web Vitals support
  • Comprehensive documentation page at /docs
Newv0.4.0

Authentication & tracking infrastructure

  • Clerk authentication with sign-in and sign-up pages
  • Protected dashboard routes with middleware
  • Public dashboard sharing with toggleable URL
  • Tracking script with sendBeacon and fetch fallback
  • Edge Function ingest API at /api/collect
Improvedv0.3.0

Dashboard enhancements

  • Realtime visitor map with animated pulse dots
  • Sparkline charts in stat cards with trend indicators
  • Page detail panel with click-to-expand on Pages screen
  • Referrer URL drilldown on Sources screen
  • Conversion funnel visualization
  • Keyboard shortcuts (press ? for help)
Improvedv0.2.0

Dark mode & polish

  • Fixed dark mode contrast on all charts and graphs
  • World map dot visualization for country data
  • CSV export for Overview and Pages
  • Notification bell with activity feed
  • Loading skeletons for all dashboard pages
Launchv0.1.0

Initial MVP

  • Landing page with hero, features, pricing, FAQ, testimonials
  • Dashboard with Overview, Realtime, Pages, Sources, Conversions, Settings
  • Built on Untitled UI design system with React Aria Components
  • Deployed to Vercel with auto-deploy from GitHub

Stay in the loop

Subscribe via RSS, follow GitHub releases, or create an account — we'll let you know when something meaningful ships.