How it works

Catches everything.Slows nothing.

Most monitoring scripts say they catch every error. Most don't. They load late, miss the early page lifecycle, and quietly drop the issues that fire before they wake up. Here's exactly how Bloodhound is built and what it can and can't see.

550B
Inline stub, gzipped
5.8KB
Deferred main, gzipped
0ms
Render blocking
~1ms
Stub execution time
The page lifecycle

Where every monitor lives, where Bloodhound lives.

The trick is the gap between "page starts" and "your monitor wakes up." Bloodhound closes that gap with a tiny synchronous stub at the very top of <head>, then does the heavy lifting once the page is parsed.

Stub registers~1ms after first byte
Main script drains queueafter HTML parse
Batch flush every 5s+ on page-hide
Typical monitor blind spot
Bloodhound coverage
Architecture

Two scripts. One job.

They install in one click via a Shopify theme app block. No code changes to your theme.

01 · Inline stub
550 B gzipped · synchronous
  • Registers error + unhandledrejection listeners (capture phase)
  • Queues events into window.__bh_q (capped at 100)
  • Boosts the resource-timing buffer to 500 entries
02 · Deferred main
5.8 KB gzipped · non-blocking
  • Drains the stub queue on startup
  • Reads CWV retroactively via buffered: true
  • Attributes every error and script to its origin
  • Batches and ships via navigator.sendBeacon
↓ POST /ingest (batched, every 5s) ↓
03 · Ingest server
Postgres-backed · per-shop rate limit
  • Dedupes by signature, attributes by origin
  • Rolls into daily aggregates + revenue impact scoring
  • Pushes to Slack/email when error rate spikes
04 · Merchant dashboard
Embedded in Shopify admin
  • Errors grouped + ranked by revenue lost
  • Core Web Vitals trend, p75 against Google's thresholds
  • Per-app and per-script performance breakdown
What you get

The honest version.

We'd rather tell you the truth than write copy that falls apart when an engineer looks at it.

Caught

  • JavaScript errors in any inline <script> after the Bloodhound block
  • Errors in third-party app scripts loaded later in <head> or <body>
  • Errors in theme JS, async events, hydration, post-load interactions
  • Unhandled promise rejections with full message, stack, name
  • Failed fetch / XMLHttpRequest (4xx, 5xx, network errors)
  • console.error calls (and console.warn on Pro)
  • Content-Security-Policy violations
  • Core Web Vitals (LCP, CLS, INP, FCP, TTFB) from start of navigation
  • Resource timing for every script the page loaded, retroactively

Not caught

  • Errors in scripts Shopify itself injects in <head> before any theme app block can render, shopify-features, boomerang, web-pixels-manager. Almost always platform internals, not actionable for merchants.
  • Cross-origin errors from third-party scripts that don't send Access-Control-Allow-Origin. Browsers strip them to "Script error." with no info. We drop these rather than logging useless rows.

Why it's so small

Vanilla JavaScript. No framework, no dependencies, no transpilation bloat. The only library it uses is the browser's own PerformanceObserver and navigator.sendBeacon. Built deliberately to fit on a slow 3G page without becoming part of the problem it's trying to measure.

🔒

Privacy

A secret-scanner runs over every captured message and stack trace. API keys, JWTs, and private tokens are redacted before anything leaves the browser. We never capture cookies, localStorage, form input values, or session content.

🛑

Kill switch

If we ever ship a stub bug to production, every store running Bloodhound can be disabled instantly without a theme update. Add <meta name="bloodhound-disabled" content="1">anywhere in <head>. The stub returns immediately and the deferred main never initialises.

Start your 14-day free trial.

One-click install from the Shopify App Store. No credit card required.

Start free trial →

14-day free trial. Installs in one click from the Shopify App Store.