Docs · Errors
Error capture
One dependency, or one script tag, and “what broke” has data: uncaught errors and unhandled rejections from the browser and the server, attached to the incident with the release that caused them.
What it sends, and what it never does
Uncaught errors, unhandled rejections and failed requests. Never form values or request bodies.
Sampling 50%, 60 events per minute per app, 2.1 KB. Messages are redacted before they leave the page. It cannot throw into your app or block it.
Your keys are under Integrations › Error capture in your workspace: a public key for the browser, matched to an application by the page’s hostname, and one key per application for a server, which has no page to match on.
The package
Not on npm yet. The package is built and its install is documented below, but the name does not resolve until it is published. Use the script tag until it does.
Prefer the dependency where you can: pasted code never gets the fix, and an agency with thirty applications would be maintaining thirty copies.
pnpm add @keelnest/capture npm install @keelnest/capture yarn add @keelnest/capture bun add @keelnest/capture
Next.js
export { register, onRequestError } from "@keelnest/capture/next";import { init } from "@keelnest/capture";
init({
key: process.env.NEXT_PUBLIC_KEELNEST_KEY,
host: process.env.NEXT_PUBLIC_KEELNEST_HOST,
});Vite, Astro or Node
import { init } from "@keelnest/capture";
init({ key: KEELNEST_KEY, host: KEELNEST_HOST });Cloudflare Workers
import { wrap } from "@keelnest/capture";
export default {
fetch: wrap(async (request, env) => {
/* … */
}),
};The keys
# The browser half: public by design, matched to an app by the page's hostname. NEXT_PUBLIC_KEELNEST_KEY=pk_live_… NEXT_PUBLIC_KEELNEST_HOST=https://keelnest.com # The server half: this key names one application. Get it under Server. KEELNEST_KEY=pk_live_… KEELNEST_HOST=https://keelnest.com
The script tag
For an application you cannot add a dependency to — a site a client edits by hand, a builder that owns package.json, a page inside a CMS. Paste it in the <head> of the site; events are attributed to the application whose production URL matches the page.
<script async src="https://keelnest.com/e.js" data-key="pk_live_…" data-sample="0.5"></script>
A server without the package
A process has no page, so it sends its application’s own key. Import once at startup — in Next.js, instrumentation.ts.
// Keelnest server error capture. Import once at startup
// (Next.js: instrumentation.ts — otherwise your server entry file).
const KEY = process.env.KEELNEST_KEY;
const URL = "https://keelnest.com/api/ingest/errors";
export async function reportError(error, kind = "error") {
if (!KEY) return;
try {
await fetch(URL, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
key: KEY,
events: [{
runtime: "server",
kind,
message: String(error?.message ?? error),
stack: String(error?.stack ?? ""),
at: new Date().toISOString(),
}],
}),
});
} catch {
// Reporting an error must never become one.
}
}
process.on("uncaughtException", (e) => reportError(e, "uncaught"));
process.on("unhandledRejection", (e) => reportError(e, "unhandled"));Prompts for a builder
If Lovable, Bolt, Cursor or Claude Code builds the app, hand it one of these instead of the steps above.
Add Keelnest error capture to my app as a dependency: install @keelnest/capture and wire it up. If this is a Next.js app, re-export register and onRequestError from "@keelnest/capture/next" in instrumentation.ts, and call init({ key: process.env.NEXT_PUBLIC_KEELNEST_KEY, host: process.env.NEXT_PUBLIC_KEELNEST_HOST }) in instrumentation-client.ts. Otherwise call init({ key, host }) once at the top of the entry file, and on Cloudflare Workers wrap the fetch handler with wrap() from the same package. Set NEXT_PUBLIC_KEELNEST_KEY=pk_live_… and NEXT_PUBLIC_KEELNEST_HOST=https://keelnest.com in the environment; leave the server-side KEELNEST_KEY for me to fill in. Do not change anything else, and do not add any other monitoring.Add the Keelnest error capture snippet to my app. Put this script tag in the <head> of the root HTML (or the root layout): <script async src="https://keelnest.com/e.js" data-key="pk_live_…" data-sample="0.5"></script>. Do not change anything else. It must not capture form values or request bodies.
Uninstalling
Remove the dependency, or the script tag, from the application. Events stop with the next page load or the next deploy; the app’s history stays. The package itself is @keelnest/capture, MIT-licensed, with no dependencies of its own. All docs.