@trevonerd/faultline-sdk
v0.1.0
Published
Small browser and Node SDK for sending errors and logs to Faultline.
Readme
@trevonerd/faultline-sdk
Small browser and Node SDK for sending errors and structured logs to Faultline.
Created by trevonerd <[email protected]>.
Install
pnpm add @trevonerd/faultline-sdknpm install @trevonerd/faultline-sdkyarn add @trevonerd/faultline-sdkBrowser Setup
Create a project in Faultline, copy the project write key, then initialize the SDK once at application startup.
import { initFaultline } from "@trevonerd/faultline-sdk";
export const faultline = initFaultline({
endpoint: "https://your-faultline-site.netlify.app/api/ingest",
projectKey: import.meta.env.VITE_FAULTLINE_KEY,
environment: import.meta.env.MODE,
release: import.meta.env.VITE_APP_VERSION,
tags: {
app: "web",
},
});In a Vite React app, call it before rendering:
import React from "react";
import { createRoot } from "react-dom/client";
import { initFaultline } from "@trevonerd/faultline-sdk";
import { App } from "./App";
initFaultline({
endpoint: import.meta.env.VITE_FAULTLINE_ENDPOINT,
projectKey: import.meta.env.VITE_FAULTLINE_KEY,
environment: import.meta.env.MODE,
release: import.meta.env.VITE_APP_VERSION,
});
createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
);By default, the browser SDK captures:
window.errorwindow.unhandledrejection
You can disable either one:
initFaultline({
endpoint: "https://your-faultline-site.netlify.app/api/ingest",
projectKey: import.meta.env.VITE_FAULTLINE_KEY,
autoCaptureErrors: false,
autoCaptureRejections: false,
});Node And Server Setup
Faultline also works in Node 18+ runtimes with built-in fetch.
import { initFaultline } from "@trevonerd/faultline-sdk";
const faultline = initFaultline({
endpoint: process.env.FAULTLINE_ENDPOINT!,
projectKey: process.env.FAULTLINE_KEY!,
environment: process.env.NODE_ENV,
release: process.env.APP_VERSION,
tags: {
app: "api",
},
});
try {
await runJob();
} catch (error) {
faultline.captureException(error, { job: "nightly-sync" });
await faultline.flush();
throw error;
}For older runtimes, pass your own fetch implementation:
import { initFaultline } from "@trevonerd/faultline-sdk";
import fetch from "node-fetch";
initFaultline({
endpoint: process.env.FAULTLINE_ENDPOINT!,
projectKey: process.env.FAULTLINE_KEY!,
fetch,
});Capturing Errors
import { captureException } from "@trevonerd/faultline-sdk";
try {
riskyOperation();
} catch (error) {
captureException(error, {
route: "/checkout",
cartId: "cart_123",
});
}You can also use the returned client:
const faultline = initFaultline({
endpoint: "https://your-faultline-site.netlify.app/api/ingest",
projectKey: "flk_...",
});
faultline.captureException(new Error("Payment failed"));Capturing Messages
Use captureMessage for issue-style events that are not thrown errors.
import { captureMessage } from "@trevonerd/faultline-sdk";
captureMessage("Checkout failed validation", {
level: "warning",
context: {
step: "shipping",
},
tags: {
feature: "checkout",
},
});Sending Logs
Use log for structured diagnostics that should appear in Faultline logs, not grouped issues.
import { log } from "@trevonerd/faultline-sdk";
log("info", "Checkout opened", {
cartId: "cart_123",
});
log("debug", "Payment provider response", {
provider: "stripe",
status: 200,
});Supported levels are:
type Severity = "fatal" | "error" | "warning" | "info" | "debug";Breadcrumbs
Breadcrumbs are attached to future captured events and logs.
import { addBreadcrumb } from "@trevonerd/faultline-sdk";
addBreadcrumb({
category: "ui",
message: "Clicked pay button",
level: "info",
data: {
component: "CheckoutForm",
},
});The SDK keeps the latest 40 breadcrumbs by default. Change this with maxBreadcrumbs.
User, Tags, Environment, And Release
import { setTag, setTags, setUser } from "@trevonerd/faultline-sdk";
setUser({
id: "user_123",
email: "[email protected]",
});
setTag("region", "eu");
setTags({
app: "dashboard",
plan: "personal",
});environment, release, and initial tags are configured in initFaultline.
initFaultline({
endpoint: "https://your-faultline-site.netlify.app/api/ingest",
projectKey: "flk_...",
environment: "production",
release: "1.4.0",
tags: {
app: "marketing-site",
},
});Flushing Before Shutdown
In browsers, the SDK uses keepalive for small requests. In server code, call flush() before
the process exits or before rethrowing fatal errors.
import { captureException, flush } from "@trevonerd/faultline-sdk";
process.on("uncaughtException", async (error) => {
captureException(error);
await flush();
process.exit(1);
});Write Keys And Allowed Origins
The project write key is required by Faultline ingestion:
POST /api/ingest
X-Faultline-Key: flk_...Browser write keys are visible in client-side bundles. Treat them as scoped write-only keys, not admin secrets. For browser projects, configure allowed origins in Faultline whenever possible.
Recommended browser environment variables:
VITE_FAULTLINE_ENDPOINT=https://your-faultline-site.netlify.app/api/ingest
VITE_FAULTLINE_KEY=flk_...
VITE_APP_VERSION=1.4.0Recommended Node environment variables:
FAULTLINE_ENDPOINT=https://your-faultline-site.netlify.app/api/ingest
FAULTLINE_KEY=flk_...
APP_VERSION=1.4.0Never commit production write keys, admin passwords, session secrets, or real production data.
Local Redaction
The SDK filters obvious secret fields before sending payloads. Matching keys include:
passwordsecrettokencookieauthorizationapiKeyapi_key
Faultline also redacts again on the server before storage.
Publishing
From the repository root:
pnpm install
pnpm sdk:check
pnpm sdk:pack:dryLog in to npm:
npm loginPublish:
pnpm sdk:publishThe package publishes as public scoped npm package @trevonerd/faultline-sdk.
