Website QA

Installing the widget

One script tag, what it costs, and how to confirm it is live.

The tag

<script async src="https://your-app/w.js" data-wq-key="wq_a7k9vd9pnw5imawe"></script>

Put it before </body> on every page you want reportable. async matters: the widget must never delay your page.

The key is public. It is embedded in a script tag on a website — treat it as an identifier, not a secret. What stops it being abused is allowed origins.

If a tag attribute is awkward in your setup, the key can ride on the URL instead:

<script async src="https://your-app/w.js?k=wq_a7k9vd9pnw5imawe"></script>

What it costs your visitors

FileSizeWhen it loads
w.js8.4 kB gzipOn page load, async
w-shot.js11 kB gzipOnly once someone starts a report

The screenshot renderer and the selector generator live in the second file. A visitor who never reports a bug never downloads them.

For scale: a common performance budget is 170 kB of compressed JavaScript for a whole page on mobile. The widget is about 5% of that, and it is off the critical path.

Confirming it is live

The widget calls home once on boot to fetch its configuration. That first call is also the install check: the project's install page flips to ✓ Installed with a timestamp. Reload the page after deploying the tag.

If it stays on "Waiting for the first page load":

  • Look for w.js in the Network tab. A 404 means the src is wrong.
  • A 404 from /api/ingest/<key> means the key does not match a project.
  • Check the tag is actually in the deployed HTML, not just in your local build.

Single-page apps

Nothing to do. The widget reads location.href when a report is sent, so React Router, Next.js and friends record whichever route the reporter was on.

One thing to know: the error prompt offers each failure once per route, not once per page load — an SPA never reloads, so "once per load" would mean once per session.

Content Security Policy

If your site sends a CSP, the widget needs three things:

script-src  https://your-app;
connect-src https://your-app;
img-src     data:;

img-src data: is for the screenshot: it is built in the browser as a data URL before being uploaded. Without it, reports still send, just without images.

Errors thrown before the widget loads

Because the tag is async, an error thrown in the first moments of page load can happen before the capture buffers are installed. Those are not recorded. Every error after boot is.

On this page