@vibemonitor/nextjs
v0.1.0
Published
Vibemonitor Next.js SDK — single install, routes to browser/node/edge impls via conditional exports.
Maintainers
Readme
@vibemonitor/nextjs
One-install Vibemonitor SDK for Next.js. Automatically routes to the right runtime-specific implementation (browser / Node / edge) via conditional exports.
Why a meta-package?
Next.js runs your code in three separate JavaScript runtimes, and each needs its own vibemonitor.init() call:
| Runtime | Where your code runs |
|---|---|
| Browser | Client components, hooks, event handlers |
| Node.js | Server components (SSR), API routes (app/api/**) |
| Edge | middleware.ts, routes with export const runtime = 'edge' |
@vibemonitor/nextjs is a thin wrapper that uses package.json conditional exports so you import the same package name in all three places. The bundler picks the right implementation automatically.
Installation
npm install @vibemonitor/nextjsThis transitively installs @vibemonitor/browser + @vibemonitor/node + @vibemonitor/core. You never install those directly.
Environment variables
Add to .env.local:
# Browser — baked into the client JS bundle at build time.
# NEXT_PUBLIC_ prefix makes it readable in client components.
NEXT_PUBLIC_VIBEMONITOR_API_KEY=vmsdk_browser_token_here
# Server — stays on the server, never shipped to browser.
VIBEMONITOR_API_KEY=vmsdk_server_token_here
# Optional — toggle SDK on/off without code changes
VIBEMONITOR_ENABLED=true
# Optional — emit [vibemonitor] diagnostic stderr lines during debugging
VIBEMONITOR_DEBUG=falseGet your tokens from the Vibemonitor dashboard → Settings → API Keys.
Setup — three files
File 1 · src/instrumentation-client.ts (browser runtime)
Next.js auto-loads this file in the browser bundle. Create it at exactly this path.
import vibemonitor from "@vibemonitor/nextjs";
vibemonitor.init({
apiKey: process.env.NEXT_PUBLIC_VIBEMONITOR_API_KEY!,
service: "my-frontend",
environment: process.env.NODE_ENV,
});File 2 · src/instrumentation.ts (router for server runtimes)
Next.js auto-loads this file at server startup. It dispatches to the right config based on process.env.NEXT_RUNTIME.
export async function register() {
if (process.env.NEXT_RUNTIME === "nodejs") {
await import("../vibemonitor.server.config");
}
if (process.env.NEXT_RUNTIME === "edge") {
await import("../vibemonitor.edge.config");
}
}File 3 · vibemonitor.server.config.ts (Node.js runtime)
Put this at the repo root (or wherever instrumentation.ts imports from).
import vibemonitor from "@vibemonitor/nextjs";
vibemonitor.init({
apiKey: process.env.VIBEMONITOR_API_KEY!,
service: "my-app-server",
environment: process.env.NODE_ENV,
});File 4 · vibemonitor.edge.config.ts (Edge runtime — only if you use middleware)
Skip this file if your app has no middleware.ts and no runtime: 'edge' routes.
import vibemonitor from "@vibemonitor/nextjs";
vibemonitor.init({
apiKey: process.env.VIBEMONITOR_API_KEY!,
service: "my-app-edge",
});What gets captured per runtime
| Runtime | Captured automatically |
|---|---|
| Browser | console.log/info/warn/error/debug, window.onerror, unhandled promise rejections, explicit vibemonitor.log() |
| Node.js | console.*, process.on('uncaughtException' / 'unhandledRejection'), explicit calls, SIGTERM/SIGINT graceful flush |
| Edge | console.*, explicit calls (no window, no process hooks available) |
You can also manually log structured events from anywhere:
import vibemonitor from "@vibemonitor/nextjs";
vibemonitor.log("INFO", "Checkout completed", {
userId: "u_123",
amount: 49.99,
});Configuration reference
Full list of options (all optional except apiKey):
vibemonitor.init({
// Required
apiKey: "vmsdk_xxx",
// Identification
service: "my-app", // defaults to hostname / auto-detected
environment: "production", // env var: VIBEMONITOR_ENV
version: "2.3.1", // env var: VIBEMONITOR_VERSION
// Endpoint — rarely overridden
endpoint: "https://api.vibemonitor.ai/api/v1/ingest/logs",
// Master switches
enabled: true, // env: VIBEMONITOR_ENABLED, NEXT_PUBLIC_VIBEMONITOR_ENABLED
debug: false, // env: VIBEMONITOR_DEBUG, NEXT_PUBLIC_VIBEMONITOR_DEBUG
// Transport tuning
flushIntervalMs: 2000,
maxQueueSize: 1000,
batchSize: 50,
// Capture layers (turn off if unwanted)
captureConsole: true,
captureGlobalErrors: true,
// PII scrubbing
scrubPatterns: ["email", "jwt", "oauth_code", ...], // defaults to full list
customScrubPatterns: { myId: /CUST-\d+/g },
// Hook to mutate or drop entries before network send
beforeSend: (entry) => entry, // return null to drop
});Precedence for every option
init({ option: value }) ← kwarg wins
↓ else
VIBEMONITOR_<NAME> env var (server runtime)
↓ else
NEXT_PUBLIC_VIBEMONITOR_<NAME> env var (browser runtime, bundled at build time)
↓ else
Hardcoded SDK defaultHow routing works under the hood
package.json conditional exports:
"browser" → dist/browser.js (wraps @vibemonitor/browser)
"edge-light" → dist/browser.js (edge APIs ≈ browser subset)
"workerd" → dist/browser.js (Cloudflare Workers)
"node" → dist/node.js (wraps @vibemonitor/node)
"default" → dist/browser.js (fallback)Next.js's bundler picks the right condition per runtime. Vite, webpack, esbuild all honor these. You never touch this mechanism.
FAQ
Q: Do I need middleware to use Vibemonitor?
No. middleware.ts is only needed for edge-runtime code. If you don't have it, skip File 4.
Q: Can I disable capture in dev?
Yes. Set VIBEMONITOR_ENABLED=false in .env.local. The SDK becomes a complete no-op (no network, no listeners).
Q: Are my server tokens exposed in the browser bundle?
Only env vars prefixed NEXT_PUBLIC_ get baked into the browser bundle. Use VIBEMONITOR_API_KEY (no prefix) for server-only tokens.
Q: Can I use a different token for server vs browser?
Yes — recommended. Mint two tokens in your Vibemonitor dashboard, set them as NEXT_PUBLIC_VIBEMONITOR_API_KEY and VIBEMONITOR_API_KEY. Revoking one doesn't affect the other.
Q: What if the workflow says "404 Not Found" when hitting the endpoint?
Your endpoint URL is wrong. Default is https://api.vibemonitor.ai/api/v1/ingest/logs. If you're running vm-api locally, override with endpoint: "http://localhost:8000/api/v1/ingest/logs".
License
Proprietary. See LICENSE.
