Changelog

What we've shipped.

Real release notes — features, improvements, fixes, and the things we've removed on purpose.

Observability hardening — global error boundary, centralized identity, quieter alerts

Three quiet-but-important fixes to the error-monitoring and analytics layer. Root-layout render errors now actually reach Sentry instead of vanishing into Next's default fallback. Your PostHog distinct_id and Sentry user binding are now driven by the real Supabase auth state on every device — sign-in, token refresh, and sign-out are all wired through one listener instead of being scattered across login forms, signup forms, and the checkout page (which left you anonymous everywhere in between). And one class of Firefox-specific browser-extension noise that was leaking into the production alert feed is now filtered at the SDK level. No visible UI change — but the next time something breaks for a real user, we'll see it cleaner and faster.

  • new

    app/global-error.tsx — the App Router root error boundary @sentry/nextjs requires. Catches errors thrown from the root layout itself and any render-time error that escapes a nested error.tsx. Without this file Sentry literally never sees them; the user just gets Next's blank fallback page. Now they reach the dashboard with a stack trace.

  • improved

    PostHog identify and Sentry user binding moved to a single onAuthStateChange listener (the same one that already handles session-expired redirects). Before, only the checkout-success page tied your session to your user record — every other auth path (login, signup, Google OAuth, background token refresh) left you anonymous in PostHog and untagged in Sentry until conversion. Now the identity stitches the moment Supabase reports a session, and resets cleanly on sign-out so the next person on a shared browser gets a fresh anonymous id instead of inheriting yours. One file, one source of truth, instead of identify/setUser calls scattered across six sign-in/sign-out call sites that would have rotted within a release or two.

  • improved

    Sentry Logs product opted in across browser, server, and edge runtimes via enableLogs: true. Sets up Sentry.logger.* call sites for state-machine anomalies that aren't exceptions but are worth surfacing alongside errors — trace-correlated structured logs in the dashboard without standing up a separate logging stack.

  • fixed

    Firefox SyntaxError noise from the next/Script injection path is now filtered at the SDK level. The existing ignoreErrors regex already covered Chromium V8 ("Invalid or unexpected token") and Safari/JSC ("Unexpected EOF" / "Unexpected end of input") but missed Firefox SpiderMonkey's wording ("'…' string literal contains an unescaped line break"). The trigger is third-party scripts that translator extensions, ad blockers, and a few Asia-region ISPs inject into document.body — none of which we author or can fix from our side. We caught one event from a Firefox-on-Mac visitor with US geo and a Shanghai timezone (the canonical translator-extension fingerprint); future occurrences across all three engines now drop client-side before they ever reach the alert feed.

  • fixed

    Misleading comment in sentry.server.config.ts that claimed `integrations: []` disabled all default integrations. In @sentry/nextjs v10 array-form integrations merge with the SDK defaults rather than replacing them — the empty array is effectively a no-op slot for future per-integration tweaks. Behavior was always correct; the comment is now too.

Help & support page, every integration in beta, dashboard mobile pass, IndexNow + RSS

New /dashboard/support page funnels every help request through the right inbox bucket with auto-attached account context — no ticket system, no chat widget, just prefilled mailtos that route categorized to support@getsignalroute.com. Every shipped integration is now flagged Beta while we harden edge cases — the Connect button still works, the badge just sets honest expectations. Dashboard mobile pass: every page reflowed for thumb-reach typing and tap targets, the agency clients table becomes stacked cards on phones, KPI strips and recent-feedback rows fit a 375px screen. Plus IndexNow submission to Bing/Yandex/Naver/Seznam/Yep, an RSS feed at /feed.xml, explicit AI-crawler allow rules in robots.txt, /humans.txt, the workspace switcher fix on mobile, and a hardening pass on the Google OAuth callback URL.

  • new

    /dashboard/support — a single email-first help page with five categorized mailto buttons (bug report, billing, feature request, integration help, general question). Each one auto-attaches your workspace ID, slug, subscription status, and signed-in email so support resolves the account on first read. Reachable from the workspace nav rail and the user-menu dropdown.

  • new

    Every shipped integration is now badged Beta. The wiring is live, the Connect flow still works, and existing connections keep firing — the badge just communicates that we're still hardening edge cases. Coming-soon integrations stay coming-soon. Once the connect-disconnect-reconnect path has been pounded on for another few weeks, individual integrations will graduate back to Live one at a time.

  • new

    IndexNow submission. Daily cron pings the consortium endpoint (api.indexnow.org) with the full sitemap so Bing, Yandex, Naver, Seznam, and Yep — and by extension ChatGPT, Copilot, Claude search, and Perplexity, which all source from Bing — index new content within minutes instead of waiting on organic crawl. Manual CLI at scripts/submit-indexnow.ts for ad-hoc pushes ahead of the daily cron.

  • new

    RSS feed at /feed.xml. Picked up by classic feed readers, Slack unfurls, and the LLM ingestion paths that prefer structured streams over HTML scraping. Auto-discovery wired in the marketing layout via <link rel="alternate" type="application/rss+xml"> so feed readers detect it from any page.

  • new

    Explicit allow rules for 11 AI crawlers in robots.txt — GPTBot, ChatGPT-User, OAI-SearchBot, ClaudeBot, Claude-Web, anthropic-ai, Google-Extended, PerplexityBot, Perplexity-User, AppleBot-Extended, CCBot. The wildcard rule already let them in; the explicit entries make intent crystal-clear (yes, please cite us) and give us a single place to block any one of them in the future.

  • new

    /humans.txt — the standard credit / stack file. Low SEO impact, but it's a small trust signal worth half a kilobyte.

  • improved

    Mobile-first pass on every dashboard page. KPI strips collapsed text-3xl → text-2xl on mobile and tightened p-5 → p-4 padding so 160px-wide cards on a 375px phone don't feel oversized. Recent-feedback rows on Overview now show the customer's full name even when feedback is long. Reviews page filter selects switched from fixed-width pills (which overflowed at 375px) to a half-width grid that wraps cleanly. Locations rows stack on mobile with full-width action buttons. The agency clients table is now mobile cards (Logo + name + actions menu, status + date subline, 3-up metrics strip, and a copy/QR/open action row); the dense desktop table is preserved at sm+. Settings form: phone/contact, font selector, and address state/zip inputs now scale correctly on mobile instead of overflowing at fixed widths.

  • improved

    Referrals page got a full mobile redesign — Share button now reads as a button instead of plain text next to the primary Copy, link preview wraps with break-all instead of clipping, the "Other links" rows stack name + URL + a real Copy button on mobile, and the referrals list renders as cards on phones with the table preserved on tablet+.

  • improved

    Trial banner on past_due / canceled now stacks the message above a full-width tap-friendly CTA on mobile (was an h-7 / 28px button hard to hit on a phone).

  • improved

    Account billing buttons no longer use size="sm" (32px) on mobile — primary Subscribe / Resubscribe / Update payment is full-width h-10 with the price label readable, and the Billing portal link gets a border on mobile so it reads as a button instead of an inline text link.

  • fixed

    Continue with Google in production no longer redirects through localhost. The callback URL now prefers NEXT_PUBLIC_APP_URL — Supabase only honors redirectTo when it's on the dashboard's allow-list and falls back to the Site URL otherwise; pinning to the canonical host keeps OAuth on production even from preview deploys or stale cookie domains.

  • fixed

    Mobile workspace-switcher dropdown stopped opening off-screen. The menu was opening side="right" and pushing past the right edge of the mobile sheet drawer; on mobile it now opens side="bottom" with a viewport-bounded width, on desktop it keeps the original placement that opens into the main content area.

  • fixed

    Sitemap was rendering invalid XML — the dynamic OG image URLs in <image:loc> contained literal `&description=` which the XML parser interpreted as an entity reference. Now properly escaped to `&amp;description=`; full sitemap parses clean.

Sign in with Google, SEO depth pass, perf round, security audit

One-tap Google sign-in on signup and login. SEO round two: visible breadcrumbs, ItemList schema across hub pages, real depth on every (industry, city) page, an image sitemap, and a richer web manifest. Performance pass: dashboard KPIs collapsed into one RPC, marketing fonts no longer load on dashboard/auth/checkout, unload-time Web Vitals actually deliver. Security audit batch tightens rate limits, redirect/path validation, and cron auth across the API surface.

  • new

    Sign in with Google. Both /auth/login and /auth/sign-up now have a Continue with Google button above the email/password form. Brand-new accounts created via Google land in the same onboarding funnel as email signups (business name → reply-to verify → checkout) so nothing is skipped.

  • new

    Visible breadcrumbs on /blog, /compare, /for, /for/<city>, /integrations, and /learn detail pages — pairs with the existing BreadcrumbList JSON-LD so users and Google see the same hierarchy.

  • new

    ItemList schema on /blog, /compare, /for, /integrations, /learn, /tools — every hub page is now eligible for Google's carousel rich result on SERP listings.

  • new

    FAQPage schema on /features, /how-it-works, and /no-review-gating — the three highest-traffic pages that were missing FAQ rich-result eligibility.

  • new

    Programmatic /for/<industry>/<city> pages now ship three H2 sections (why review software matters here, how SignalRoute works for <city>, FAQ with four entries), a compliance callout linking /no-review-gating, and inline links to /features, /pricing, /how-it-works. Defends hundreds of city pages against thin-content classification.

  • new

    Footer gained three columns — Compare (4 competitors + a link to the rest), Glossary (4 terms), and Use cases (4 landing pages that were previously orphan-indexed) — so internal links flow into pages that were sitting outside the link graph.

  • new

    Image sitemap — every blog post, comparison, industry, city, integration, and glossary page now declares its hero / OG image so Google Images can crawl them as first-class results.

  • new

    Static OG fallback at /og-default.png. If /api/og is rate-limited or mid-deploy, social previews on Twitter / Slack / iMessage still render a real card instead of a broken image.

  • new

    /.well-known/security.txt — standard vulnerability-disclosure contact + policy URL so security researchers know where to send reports.

  • improved

    Hub-page card links read like real link text now. "See the page" / "Learn more" / "Compare" became "Review software for plumbers", "vs Birdeye", "Read: what is review gating?", "Connect with Housecall Pro" — both more skimmable and stronger anchor text.

  • improved

    Sitemap is now generated by walking the app/(marketing) directory plus the existing data sources. New marketing pages are picked up automatically — no list to keep in sync.

  • improved

    /privacy and /terms now declare their own canonicals + meaningful descriptions instead of inheriting "/" from the root layout. Homepage also gets its own metadata block.

  • improved

    Web app manifest filled in with start_url, scope, id, description, language, categories, and a separate "maskable" icon entry — required for Add to Home Screen to look right on Android, and for PWA install prompts.

  • improved

    Dashboard KPI strip reads through one Postgres RPC (dashboard_company_metrics) that returns lifetime + 7d / 14d aggregates in a single round trip — was four parallel queries plus a full reviews scan for the average. Agency clients page got the same treatment with a grouped-aggregate RPC.

  • improved

    Marketing-only Instrument Serif font no longer loads on dashboard, auth, checkout, or embed routes — saves ~20KB on every authenticated page view.

  • improved

    Web Vitals reporter now uses navigator.sendBeacon. LCP / CLS samples that fire at unload time actually deliver instead of getting cut off — our perf data is finally complete.

  • improved

    Static asset caching: /_next/static/* served immutable, /images and /fonts served 7-day with stale-while-revalidate. Repeat-visit and same-session navigation are noticeably faster.

  • improved

    Falling-pattern hero animation now waits for the first idle frame before starting, so the paint loop stops competing with LCP on first load.

  • improved

    Cron-route auth extracted to one helper (lib/cron-auth.ts) and applied across all seven /api/cron/* handlers — timing-safe Bearer compare and one consistent failure response replace seven hand-rolled string checks.

  • improved

    Inbound webhook is now rate-limited by token AND by IP — a leaked token can no longer be hammered from a distributed botnet without hitting the token-scoped cap. Email-verify endpoint gains a 10-per-5-min per-IP limit so the HMAC token can't be brute-forced if any partial material leaks.

  • improved

    Reset-password gate uses Supabase-validated auth (getUser) instead of a cookie read (getSession), so the UI matches the real auth boundary the actual password change runs through.

  • improved

    Trial-history scan now walks up to 100 historical Stripe customers per email (was 10) — power-trialers with a long Stripe history can no longer slip past the prior-subscription check.

  • improved

    HousecallPro webhook accepts its token via header (X-HCP-Webhook-Token or Authorization: Bearer) in addition to the legacy ?token= query string. Headers don't leak into proxy / browser-history / log pipelines the way query strings do.

  • fixed

    Place-ID extractor follows the redirect chain and revalidates the FINAL URL against the Google host allowlist. A poisoned or compromised goo.gl redirect can no longer slip an SSRF target past the first-hop check.

  • fixed

    Logo-upload DELETE now parses the URL and checks path segments exactly. A specially-crafted user id like "logs" can no longer match a substring inside /blogs/-prefixed paths.

  • fixed

    Referral self-credit also rejects when the referrer and referee share an email — closes the alias-account exploit (one human on two Supabase auth accounts) that the existing user_id check missed.

  • fixed

    v1 API endpoints now inherit a per-IP rate-limit floor at the handler level, so a route added without an explicit cap still has one.

  • fixed

    Logo images on the dashboard sidebar and mobile top bar had empty alt text. Now declared properly — screen readers announce "SignalRoute" instead of skipping the brand entirely.

  • fixed

    /auth/sign-up and /auth/login dropped from the sitemap — the sitemap was contradicting our own /auth/ block in robots.txt.

  • removed

    /public/sw.js — orphaned service worker that no code ever registered. Browsers don't see it and it's gone from the bundle.

Send review requests to anyone + drillable activity + verified reply-to + authority engine

Send a review request straight from the dashboard to any email — no integration required, SMS coming soon. Every send (manual or integration-driven) flows through the same activity feed; every row is drillable to a per-event detail page with full lifecycle, captured HTML, parsed UA, country flag, and originating-request linkbacks. Customer-facing reply-to is now a verified company email with onboarding capture + click-through confirmation, replacing the silent fallback to your personal Gmail. Plus: schema markup on every key page, /llms.txt for AI crawlers, /search site search, branded review-request emails, a public /contact page, the authority engine (author bylines + Person JSON-LD + /research + /press + newsletter), 10 plumber-city programmatic pages, 30-day money-back guarantee, three more inbound integrations, QuickBooks OAuth beta, and a reserved-slug guard.

  • new

    Send a review request to anyone, right from the dashboard. New "Send review request" button on Overview and Reviews opens a dialog — type any email, send the same template integrations use, and the email lands in the activity feed with full lifecycle (delivered/opened/clicked) tracking. SMS option visible as coming-soon. No integration required.

  • new

    Verified company reply-to email is now required before review-request emails can be sent. Customer replies route to the inbox you control — never to a personal Gmail. One-click verify in Customize, plus an unmissable banner on Overview and Reviews until you do.

  • new

    Onboarding now collects + verifies your customer reply-to email up front. New signups walk through one extra step right after the business name; the confirmation email lands in your inbox while you finish the rest of setup so review requests can fire the moment your first integration triggers.

  • new

    Activity feed rows are drillable. Click any page view, QR scan, link click, platform click, review, or email send to open a per-event detail page — full metadata, parsed user agent, country flag, IP fingerprint, originating review-request, and a deep-link to the email that delivered it (when applicable).

  • new

    Activity feed logs every review-request email — click any email row to view the exact HTML that was delivered, plus a lifecycle timeline (sent → delivered → opened → clicked → bounced). QR scans are split out from manual taps so you can finally see whether your printed materials are pulling weight.

  • new

    Author byline + Person JSON-LD on every blog post. Search engines and AI crawlers can now connect blog posts to their author's profile (sameAs socials, author URL), strengthening the topical authority signal Google leans on for E-E-A-T.

  • new

    /about/byron-wade founder profile page — full Person JSON-LD with title, organization, sameAs links, and a recap of writing/research/press appearances.

  • new

    /research index — a hub for original SignalRoute studies and data drops, the canonical landing spot for every long-form piece other sites cite.

  • new

    /press page with a citations data layer (lib/press.ts) — every place we've been quoted or written about, in one referenceable list.

  • new

    Newsletter signup in the marketing footer — server action, no third-party form embed, captured via the same backend as inbound webhooks.

  • new

    Programmatic SEO landing pages at /for/[industry]/[city] — 10 plumber-city pages live (Phoenix, Houston, Dallas, etc.) with serviceArea JSON-LD, build-time quality gate, and the data layer ready to spin up more industries.

  • new

    /guide/google-reviews — pillar page plus a companion blog post, common-mistakes section, intro framing, and primary-source citations. The first of a series of guides feeding the topical authority graph.

  • new

    30-day money-back guarantee on /pricing, plus a comparison-shopper rail with the three tiers side-by-side. Lower the trust barrier without lowering the price.

  • new

    Site search at /search — basic search across blog, glossary, comparisons, industries, and integrations. Reachable from the WebSite SearchAction so Google can surface it as a sitelinks search box too.

  • new

    /llms.txt route — a structured AI-crawler manifest so ChatGPT, Claude, Perplexity, and similar tools can find canonical content without scraping HTML.

  • new

    Live activity tracking on the analytics dashboard — presence count, real-time event feed, and geo distribution from anonymous click + view events.

  • new

    Public /contact page — clear support routing, deflection to common docs, and a personal note from the founder.

  • new

    Workspace settings expanded — owners can now publish phone, website, tagline, address, and business hours from /dashboard/customize. The data flows through to public review pages and emails.

  • new

    Branded review-request emails — every customer now sees the business's logo and brand color in the email header, and replies route back to the business's chosen reply-to address instead of ours. Tint-aware CTAs keep contrast readable on any color.

  • new

    HousecallPro setup is fully self-serve — webhook URL reveal, copy-to-clipboard, a self-test button, and click-by-click setup steps live in the dashboard so operators can wire it up without our help.

  • new

    HubSpot, WordPress, and Webflow joined the inbound-webhook list — three more tools that can fire SignalRoute review requests automatically from a form or contact event.

  • new

    QuickBooks Online OAuth is in beta — connect your QBO account so paid invoices automatically schedule a review request to the customer.

  • new

    Reserved-slug guard — names like /admin, /pricing, /login, /api, etc. can no longer be registered as a company slug. Existing companies are unaffected; only new signups + slug changes hit the deny-list.

  • new

    Meta Pixel + Conversions API wired with browser/server dedup. Server-side conversions recover ~30% of attribution lost to iOS 14.5+ ATT and avoid double-counting via shared event_id.

  • new

    Organic-funnel attribution — every signup carries a first_touch_source captured the first time the visitor lands on the site, so we can finally see which channels actually convert.

  • new

    Four new ad/SEO landing pages under /lp — purpose-built for paid acquisition tests with focused copy and a single CTA.

  • improved

    Schema-markup pass across the site for richer Google + AI results: WebSite + FAQ + SearchAction on the homepage, SoftwareApplication on every free tool page, breadcrumb JSON-LD on docs / privacy / terms.

  • improved

    Per-template Open Graph images on the integrations index, integration detail pages, and the learn glossary — link previews on Twitter / Slack / iMessage now show a card tailored to the page instead of a generic logo.

  • improved

    Sitemap now covers per-provider /integrations/* pages and 9 previously-missing static URLs, so search engines can find every public route in one fetch.

  • improved

    Reviews dashboard — Google and private review cards redesigned around shared row primitives. Denser, brand-stamped, and the active source-filter pill uses inverted contrast so it actually reads as the active state.

  • improved

    Wallet pass is now a business card, not a review-loop link — saves the business's contact info and a tap-to-review action, so customers keep the pass even after they've left a review.

  • improved

    Agency dashboard separates agencies from locations and adds a typed-confirm flow before deleting a client, so a misclick can't take down a customer's QR code.

  • fixed

    Robots.txt no longer points crawlers at the retired /r/* URL pattern. The new canonical is /<slug>; old links 301 to it.

  • fixed

    Public review pages now record their own page-view tracking reliably — wrapped the tracking write in after() so it runs after the response ships, instead of getting cut off mid-flight.

  • fixed

    Live tracking writes use the admin client (so RLS doesn't silently drop them) and the live feed API requires real auth (so clients can't request someone else's feed).

  • fixed

    PostHog's first-touch source register now waits for the SDK loaded callback — earlier it could fire before posthog was ready and the source got dropped.

  • fixed

    Several smaller fixes: API key last_used_at now updates on use, inbound-webhook counters increment atomically, the customize-page logo lost some stale image styling, and empty company-id batches are guarded so a logged event with no companies never hits the DB with an unsafe filter.

  • fixed

    Full-site audit cleanup — orphaned utilities removed, type safety tightened across analytics + integration paths, env-var documentation refreshed, and Person JSON-LD now omits empty sameAs arrays (cleaner schema for crawlers).

  • fixed

    Compact authority byline only renders the title when one is explicitly passed — fixes a pass-through that was showing 'undefined' on a couple of programmatic pages.

  • removed

    /r/<slug> is retired in favor of canonical /<slug>. Existing /r/<slug> URLs still work — they 301 to the new path — but every newly-generated link uses the short form. Two characters less in every QR code, one fewer hop in every email.

Mobile polish, content pass, comped accounts, Google Wallet, roadmap

Big polish pass: mobile responsive across the whole site, tighter copy and trust signals, Google Wallet save coming soon, a public roadmap, and dedicated chrome for free comped accounts.

  • new

    Inbound webhooks. Five new integrations went live in one move — Stripe, Square, GoHighLevel, and Calendly join the existing list, plus a Generic JSON template for everything else. Pick the source tool, we generate a URL, you paste it into the tool's webhook settings. We extract customer info from the payload (name, email, phone) and schedule a review request automatically. Stripe and Calendly signatures are verified. Configurable post-event delay so a Calendly meeting can fire its review ask 60 minutes after the appointment ends. Lives at Integrations → Inbound webhooks.

  • new

    API keys are now self-serve in the dashboard. Create scoped keys for Zapier, Make, n8n, or your own backend without contacting support. 25+ granular scopes mean you can grant a zap exactly the permissions it needs and nothing more. Live + test modes share the same endpoints. The plaintext is shown once on creation; we keep only a hash, so revoke + recreate is the recovery path. Lives at Integrations → API keys.

  • new

    Outbound webhooks are now self-serve in the dashboard. Paste a URL — Slack, Discord, Microsoft Teams, IFTTT, n8n, your own backend — pick which events you care about, and review activity flows there in real time. Each endpoint gets its own signing secret so you can verify the request really came from us. Lives at Integrations → Outbound webhooks.

  • new

    Nine new integrations on the listing — Slack, Discord, Microsoft Teams, IFTTT going live today via the new outbound-webhooks system; Mailchimp, HubSpot, Salesforce, Notion, and Twilio added as coming-soon so you know what's on the runway. Browse them at /integrations.

  • new

    Free comped accounts now have their own treatment. Instead of a trial countdown or billing banner that doesn't apply, the dashboard shows a clear "Free account · comped" indicator on the sidebar, mobile top bar, and account page — with a direct line to the founder for anything you need.

  • new

    Onboarding wizard now auto-saves your progress as you go. Step away, log out, come back another day — your answers are still there. A dismissible banner makes the restore obvious.

  • new

    Public /roadmap page — three honest stages (Next, Planned, Exploring) so you can see what we're shipping next. More wallet options, owner plugins for promos and gift cards on the 5★ page, more CRM and scheduling integrations, agency CSV export and email recap, and white-label.

  • new

    Google Wallet save support is in the runway. Your customers will soon be able to save your business as a Wallet pass on their Android phone with one tap, mirroring the Apple Wallet treatment. Both flip on the moment provisioning is finished.

  • improved

    Site-wide mobile responsiveness pass. Forms no longer zoom on iPhone, tap targets are properly sized, marketing pages don't overflow on narrow screens, and wide tables scroll instead of breaking the layout.

  • improved

    Mobile marketing nav redesign. Collapsible sections, Pricing reachable in one tap, and a sticky Start-free button so the CTA is always visible regardless of how far you scroll.

  • improved

    Compliance language across the marketing site is more careful. Softened wording around FTC + Google review policies, and removed any phrasing that could read like "we filter bad reviews" — we don't, and we never will.

  • improved

    Customer-facing review-form copy is cleaner. The low-rating reassurance bullet no longer reads as gating, the thank-you message only promises follow-up when the customer actually shared an email, and the auto-open countdown's cancel control reads naturally instead of like a debug button.

  • improved

    Auth error messages on login, signup, and password reset are now friendlier — clear plain-English reasons instead of internal-sounding error strings.

  • improved

    When a business owner lands on a broken URL, the 404 page now offers a clear path back to support — sign in to the dashboard or email us directly.

  • fixed

    Customer review pages are more resilient. A class of bug that could leave a page stuck on a stale 404 has been eliminated, transient hiccups retry automatically, and feature flags degrade gracefully instead of taking the whole page down.

  • fixed

    Several inconsistencies between the marketing site and the product: a contradicted "card on file" line on checkout success has been removed, the offline page no longer claims a sync feature we don't have, and the footer status indicator now links to the changelog instead of always claiming green.

Agencies, billing grace, mobile polish

SignalRoute for agencies — manage every client business from one dashboard, $15 wholesale, resell at $49–$99. Plus a 14-day grace window so a single declined card doesn't black out QR codes, and serious mobile polish across both dashboards.

  • new

    Agency workspace — sign up as an agency or add one to an existing account, then manage every client business from one dashboard. New /dashboard/agency with an overview (KPIs + live margin math), clients table, cross-client feedback inbox, sales kit, and settings. Free workspace, free demo client, $15/mo wholesale per active billable client, suggested resale $49–$99/mo.

  • new

    Agency wholesale Stripe billing wired end-to-end — one subscription per agency with quantity tracking active billable clients. Pause / resume / archive a client and the Stripe seat count syncs automatically with proration. Demo and paused/archived clients are excluded from the count.

  • new

    /agencies marketing page — economics, dashboard preview, sales kit overview, FAQ. Top-level Agencies link in the marketing nav.

  • new

    Four agency-specific emails — welcome, client-added confirmation, billing-activated on first checkout, and payment-failed. The agency welcome replaces the regular welcome when the workspace was created as an agency.

  • new

    14-day billing grace window. When a card declines, public review pages stay live for 14 days while we and Stripe both retry. Day 0: payment-failed email. Day 7: a warning email ("pages go offline in 7 days"). Day 14: pages redirect to a friendly inactive screen until billing is fixed. Customers' QR codes no longer black out from a single bad charge.

  • new

    Pausing or archiving an agency client immediately blocks the public review route. QR codes already in the wild stop landing customers on a working page, so an agency can actually offboard a client.

  • new

    "From the founder" section on the homepage — a short personal note from Byron about why the product exists (he ran a plumbing company, got bitten by surprise 1-stars, built the filter he wished he'd had).

  • new

    New 404 page. We make a product about routing customers to the right place. We routed you to the wrong one. The page itself is shaped like the customer-facing review form, with a fictional 1-star review of the page by you.

  • improved

    Both dashboards are now 100% mobile responsive. New hamburger menu surfaces the sidebar, page padding scales by breakpoint, header rows stack on phones, share-link cards no longer overflow the viewport, the routing page reflows so each platform row fits comfortably.

  • improved

    Mobile sidebar auto-closes when you tap a nav link instead of staying open over the new page.

  • improved

    The "this page is offline" screen got a complete rewrite — warmer copy ("we hit a snag — please contact the business directly"), avatar disc, and a separate callout for the business owner pointing back to the dashboard.

  • fixed

    Existing users couldn't reach the agency dashboard at all — the layout was bouncing them back to the regular dashboard with no signal. New /dashboard/setup-agency page lets any existing business owner spin up an agency workspace in one click.

  • fixed

    The agency dashboard rendered two stacked headers on mobile (and two side-by-side sidebars on desktop) because Next.js layouts compose. Restructured into a route group so the agency dashboard only renders its own chrome.

  • fixed

    Sidebar agency link was labeled "Add agency workspace" even when the user already had one — was reading is_agency of the currently-viewed company instead of asking whether the user owns an agency anywhere. Label flips to "Agency dashboard" the moment one exists.

  • fixed

    Two dead Quick Action links on the dashboard (/dashboard/platforms, /dashboard/settings) repointed to the actual routes (/dashboard/routing, /dashboard/customize).

Production hardening — live billing, CSP, Stripe Tax, Upstash

Behind-the-scenes production polish: switched to live Stripe keys, added a Content-Security-Policy, enabled Stripe Tax + address collection at checkout, swapped the in-memory rate limiter for an Upstash-backed one, fixed the lead-magnet form, and corrected the canonical app URL.

  • new

    Stripe Tax automatic_tax + tax_id_collection enabled in checkout — sales tax / VAT calculated based on the customer's billing address. Required to comply with US economic-nexus thresholds (e.g. $100k or 200 transactions in a state) and EU VAT.

  • new

    Content-Security-Policy header — restricts script/style/connect/frame sources to a known allowlist (Stripe, PostHog, Sentry, Supabase). Reduces XSS blast radius across every route.

  • new

    Rate limiter now backed by Upstash Redis when UPSTASH_REDIS_REST_URL is set — limits apply globally across every Vercel region instead of per-instance. Falls back to in-memory cleanly so local dev keeps working.

  • new

    Lead-magnet signups now notify the owner by email and add the lead to a Resend audience for marketing follow-up.

  • fixed

    Lead-magnet form no longer gets stuck on "Sending…" when the server action throws — wrapped in try/finally so the spinner always clears, and the server action now checks Resend's { data, error } return shape so domain-verification failures surface as real errors instead of silent ok:true.

  • fixed

    Switched production from Stripe test mode to live mode — real cards now actually charge. The two were on entirely separate Stripe accounts so the cutover required a fresh subscribe with a real card.

  • fixed

    NEXT_PUBLIC_APP_URL now matches the canonical www domain — Stripe success_url, OAuth callbacks, and share links no longer 307-redirect on first hit (which on some browsers was dropping POST state at checkout).

  • improved

    Checkout now collects a billing address (required for tax) and persists it on the Stripe customer so the billing portal and future invoices reuse it without re-prompting.

Multi-location billing, dark mode, comparison + industry pages

The biggest week of changes since launch — new dark theme, consolidated multi-location billing, 13 honest competitor comparison pages, and 8 industry landing pages.

  • new

    Dark mode site-wide using the Midnight Trust palette (Signal Blue accent on deep navy surfaces). Toggle in the header.

  • new

    Multi-location consolidated billing — one Stripe subscription scales with location count. $30 first location, $15 each additional, all on one bill.

  • new

    13 side-by-side comparison pages: vs Birdeye, Podium, NiceJob, Reputation.com, Trustpilot, Grade.us, GatherUp, ReviewTrackers, BrightLocal, Yotpo, Swell CX, Weave, Customer Lobby. Real pricing, real complaints, honest decision criteria.

  • new

    8 industry landing pages with placement ideas tailored to each vertical: plumbers, restaurants, dentists, auto repair, salons & spas, medical practices, real estate agents, fitness studios.

  • new

    Interactive review-routing demo on the homepage — drag a star rating to see exactly where the customer would land.

  • improved

    Hero rebuilt around the “2-star moment shouldn't become a 2-star review” concept. Mobile browser viewport mockup replaces the previous fake iPhone bezel.

  • improved

    /pricing combined with inline signup — sticky form on the left, pricing breakdown on the right. One less hop to the trial.

  • improved

    Auth pages redesigned as 5/12+7/12 grid with a Midnight Trust brand panel. /auth/sign-up and /auth/login now match the marketing brand.

  • improved

    Strict TypeScript enforced — pnpm build now runs full type checking on every CI run.

  • fixed

    Email-template renderer — every email was shipping with “[object Promise]” as the body in production. Now sending real HTML.

  • fixed

    Hydration mismatch in the realtime analytics clock. Time renders consistently between SSR and first client paint.

  • fixed

    Demo-mode platform clicks no longer launch real Google.com tabs while you're trying out the demo.

  • removed

    “Review gating” language across the site. SignalRoute routes happy customers to public review platforms and offers unhappy customers a private feedback channel — every customer can still post publicly. The old framing was an FTC-rule risk; the new framing is what the rule actually permits.

Try the latest today

Every change above is in production. 7-day free trial, no credit card required to start.

Start free trial