Examples
Real-world snippets for the most common Emit Vision integration patterns. Each example is self-contained and runnable as shown.
All examples assume you've already called init() once at app startup. See
the Quick Start guide if you haven't done that yet.
Browser: track a button click
Use captureEvent inside any event handler. Pass a properties object for dimensions and a tags object for filterable labels.
import { captureEvent } from "@emit-vision/sdk-js";
function handleUpgradeClick() {
captureEvent("upgrade_clicked", {
properties: {
plan: "pro",
source: "pricing_page",
},
tags: {
experiment: "pricing-v2",
},
});
}
document
.getElementById("upgrade-btn")
?.addEventListener("click", handleUpgradeClick);Events appear in the dashboard's Events tab within a few seconds.
Browser: capture a caught error
Wrap risky operations in try/catch and call captureError to send the error with context attached. See Errors for grouping and fingerprinting details.
import { captureError } from "@emit-vision/sdk-js";
async function loadUserProfile(userId: string) {
try {
const res = await fetch(`/api/users/${userId}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (err) {
captureError(err as Error, {
context: { userId, endpoint: "/api/users" },
tags: { area: "profile" },
});
throw err; // re-throw so the caller can handle it
}
}React: error boundary
A class component that catches render-phase errors and reports them before showing a fallback UI.
import React from "react";
import { captureError } from "@emit-vision/sdk-js";
interface Props {
children: React.ReactNode;
fallback?: React.ReactNode;
}
interface State {
hasError: boolean;
}
export class ErrorBoundary extends React.Component<Props, State> {
state: State = { hasError: false };
componentDidCatch(error: Error, info: React.ErrorInfo) {
captureError(error, {
context: { componentStack: info.componentStack ?? undefined },
tags: { layer: "react_boundary" },
});
}
static getDerivedStateFromError(): State {
return { hasError: true };
}
render() {
if (this.state.hasError) {
return this.props.fallback ?? <p>Something went wrong.</p>;
}
return this.props.children;
}
}Wrap any subtree you want to protect:
<ErrorBoundary fallback={<p>Failed to load dashboard.</p>}>
<Dashboard />
</ErrorBoundary>Node.js: Express middleware + flush on shutdown
Initialize once at app startup, add the middleware, and flush on process exit so buffered events aren't lost. See sdk-node Reference for all options.
import express from "express";
import { init, middleware, flush } from "@emit-vision/sdk-node";
init({
dsn: process.env.EMIT_VISION_DSN!,
environment: process.env.NODE_ENV ?? "production",
release: process.env.APP_VERSION,
});
const app = express();
app.use(middleware());
// your routes here
app.get("/", (_req, res) => res.send("ok"));
const server = app.listen(3000);
async function shutdown() {
server.close();
await flush({ timeout: 3000 });
process.exit(0);
}
process.on("SIGTERM", shutdown);
process.on("SIGINT", shutdown);User identification
Call setUser after a successful login so that subsequent events and errors carry the user's identity. See Sessions for how Emit Vision ties events into a session timeline.
import { setUser, captureEvent } from "@emit-vision/sdk-js";
async function handleLogin(credentials: { email: string; password: string }) {
const user = await api.login(credentials);
// Identify the user — all future events will include this
setUser({ id: user.id, email: user.email });
captureEvent("user_logged_in", {
properties: { method: "email" },
});
}