Integrations
Catch errors in your visitors' browsers
Add one script tag to your site and JavaScript errors in your visitors' browsers become Lampwick issues. Works in apps built with Lovable, Replit or v0.
On this page
A script tag in your site's <head> reports JavaScript errors from your visitors' browsers to Lampwick. They show up under Issues with a Browser label, next to your server's errors. It needs no package and no build step, so it also works in apps made with an AI app builder.
Requirements
- A Lampwick project. Any member of its team can create the browser key; only owners can rotate it.
- Access to your site's
index.html, or an AI app builder that can edit it for you.
Add the snippet
- Open the project's Settings and find Browser errors.
- Click Get the snippet. Lampwick creates a public browser key for the project and shows one line.
- Copy the line into the
<head>of your site'sindex.html, above the other scripts:
<script src="https://app.lampwick.dev/b.js" data-key="YOUR_BROWSER_KEY" async></script>
YOUR_BROWSER_KEY is the project's browser key, which starts with lwpub_. The snippet on the Settings page already has it filled in.
The key is meant to be in your page. It can only send errors to this project and can't read anything; the API, the MCP server and /ingest all refuse it.
Built your app with Lovable, Replit or v0?
Under Browser errors, open Built your app with an AI app builder? Paste this into its chat and copy the prompt into your builder's chat. It holds your key and reads:
Add the Lampwick error monitoring snippet to the <head> of index.html, exactly as written, before any other script:
<script src="https://app.lampwick.dev/b.js" data-key="YOUR_BROWSER_KEY" async></script>
Don't change the key or move it to an environment variable: it is a public, write-only key that is meant to be in the page. Don't wrap it in a component or install a package for it.
Check that it works
Until the first error arrives, Browser errors on the Settings page says No browser errors yet; after that, Receiving browser errors with the time of the last one. To test, open your site, then run this in the browser console:
setTimeout(() => { throw new Error('Lampwick test') })
Within a few seconds the error shows under Issues with a Browser label.
What it sends
| Captured | How |
|---|---|
| Uncaught errors | window.onerror, with the stack trace |
| Unhandled promise rejections | unhandledrejection. A rejection that isn't an Error sends only its type and a short description, never the whole object. |
console.error calls | Only with data-console on the tag |
Failed fetch() calls | Only with data-fetch: network errors and HTTP 5xx, as log lines |
| Your own reports | lampwick.captureException(error), lampwick.captureMessage(text, level) |
- Page URLs are sent without the query string and fragment, which often hold tokens. Lampwick strips them again on arrival, also from URLs inside messages.
- Errors from cross-origin scripts that the browser reports only as "Script error." are skipped: browsers give no details for them.
- Lampwick groups browser errors into issues itself, by error class, message and the file of the top stack frame. A redeploy with new bundle hashes keeps the grouping.
- Source maps are not supported yet: stack frames show positions in your bundle.
Options
Set them as attributes on the script tag:
| Attribute | What it does |
|---|---|
data-key | The project's browser key (required). |
data-release | Your app's version, such as 1.4.2. Shown as Deploy on the issue. |
data-console | Also report console.error calls. |
data-fetch | Also report failed fetch() calls. |
In your code, lampwick.setUser({ id, email }) ties errors to a signed-in user, and lampwick.flush() sends what is queued right away.
Allowed sites
Under Allowed sites, list your site's addresses, one per line: https://myapp.com, https://myapp.lovable.app or http://localhost:5173. https://*.myapp.com allows every subdomain of a domain you own. Up to 20 addresses.
With a list, requests from other sites get 403. Without one, any site can use the key. A list can't stop someone who copies the key into a script of their own; if junk shows up, an owner rotates the key under Danger zone (Rotate browser key) and you update the snippet.
Limits
| Limit | Value |
|---|---|
| Per page view | 30 errors, each distinct error once; sent in batches after 2 seconds, or sooner at 10 |
| Per request | 50 events, 64 KiB |
| Per IP address | 120 requests a minute |
| Per key | 600 events a minute, 50,000 a day, 200 new issues a day |
| Per team | Browser errors have their own monthly budget, on top of your plan's events: 50k (Free), 500k (Pro), 2.5M (Team), 10M (Business). At most a fifteenth of it per day. |
When the monthly budget is used up, browser errors are dropped until the 1st (UTC) and Settings says so; server monitoring keeps working. Push notifications for browser issues are capped at 5 per project per hour, plus one summary.
Troubleshooting
| What you see | Cause and fix |
|---|---|
| No browser errors arrive | Check that the tag is in the <head> of the page that is served, with the right data-key. If you listed Allowed sites, the address in the browser's address bar must be on the list. |
403 in the browser's network tab | The site isn't on Allowed sites. Add its exact address, with https://. |
429 | A limit above was hit. Requests are accepted again after a minute, or after an hour for the daily and monthly budgets. |
| Browser errors are paused on Settings | The team used its browser budget for today or this month. See Billing and usage. |
Stack frames point into index-3f9a2c.js | Source maps aren't supported yet. |
For errors on your server, use the Laravel package or HTTP ingest.