@autter/runtime-next
v1.5.0
Published
One-command Autter Runtime for Next.js: server OTel, request wide events, coded errors, browser tracker, relay route, edge middleware and React error boundary
Maintainers
Readme
@autter/runtime-next
One-command Autter Runtime for Next.js: server OTel, browser tracker, same-origin relay route, and a React error boundary.
Install
npm install @autter/runtime-nextSet AUTTER_RUNTIME_KEY in your environment. Then three small files.
The package has two entry points — this split is what keeps the Node OpenTelemetry SDK out of your browser bundle:
@autter/runtime-next(or@autter/runtime-next/server) — server only:instrumentation.ts, route handlers, server components.@autter/runtime-next/client— client components: browser tracker + error boundary. Never imports Node code.
1. instrumentation.ts — server tracing/errors:
export async function register() {
if (process.env.NEXT_RUNTIME === "nodejs") {
const { registerAutter } = await import("@autter/runtime-next");
registerAutter({
apiKey: process.env.AUTTER_RUNTIME_KEY!,
service: "web-app",
environment: process.env.NODE_ENV,
release: process.env.GIT_SHA,
});
}
}registerAutter passes options straight to initAutterServer, so the
server SDK's defaults apply out of the box: exporters are flushed on
process exit (autoFlush) and custom attributes are scrubbed for PII
before export (redactAttributes). See the @autter/runtime-node README
for every option; makeSafeCapture, installAutterAutoFlush, and
redactAttributes are also re-exported from this package.
2. app/api/autter-runtime/route.ts — browser relay (key stays server-side):
import { createAutterRelayRoute } from "@autter/runtime-next";
export const { POST } = createAutterRelayRoute({
apiKey: process.env.AUTTER_RUNTIME_KEY!,
});3. A client component — browser tracker + render-error boundary:
"use client";
import { initAutterBrowser, AutterErrorBoundary } from "@autter/runtime-next/client";
initAutterBrowser({
endpoint: "/api/autter-runtime",
service: "web-app",
release: process.env.NEXT_PUBLIC_GIT_SHA,
});
export function Providers({ children }: { children: React.ReactNode }) {
return (
<AutterErrorBoundary fallback={<p>Something went wrong.</p>}>
{children}
</AutterErrorBoundary>
);
}React render errors don't reach window.onerror — the boundary reports
them via captureException and then renders your fallback.
Also re-exported for convenience: captureException, captureMessage,
trackEvent, setUser, setContext, flush (from
@autter/runtime-next/client) and captureServerException,
captureServerMessage, withProcessSpan, withLlmCall, trackLlmCall,
instrumentLlmClient, emitLlmSelftestTrace (from the root /
@autter/runtime-next/server).
Importing the root entry from a client component pulls the Node OTel SDK into the browser bundle and fails the build (
fscannot be resolved). Client code must always use@autter/runtime-next/client.
LLM tracing is on automatically once registerAutter runs: Vercel AI SDK
calls with experimental_telemetry: { isEnabled: true } (and anything
wrapped in withLlmCall or an instrumentLlmClient client) are recorded at
100% — every call, with model, tokens, latency, and cost. See the
@autter/runtime-node README for the API.
Operation logging (1.4.0+)
Import withRuntimeOperation, runtimeLogger, createRuntimeLogger,
flushRuntimeLogs, and runtimeLogStats from @autter/runtime-next/server.
Initialize through the existing registerAutter call in instrumentation.ts.
These APIs require the Node runtime, a 1.4.0+ ingester, and matching platform
evidence support. Client components keep @autter/runtime-next/client.
See the operation logging guide for measured
steps, explicit business outcomes, privacy and flushing. Ordinary error logs
are diagnostics; captured exceptions and declared failed outcomes use tracing
for issue grouping.
Requests, coded errors and edge middleware (1.5.0+)
Route handlers become request summaries (always kept, request id echoed in
x-request-id); the log flush is handed to Next's after() automatically
(Next 15+, unstable_after on 14.2):
// app/api/checkout/route.ts
import { withRuntimeRequest, runtimeContext, defineRuntimeErrors, toClientError } from "@autter/runtime-next";
const billing = defineRuntimeErrors("billing", {
declined: { status: 402, message: "Payment declined", expected: true },
});
export const POST = withRuntimeRequest(async (request) => {
runtimeContext.set({ plan: "pro" });
const ok = await charge(await request.json());
if (!ok) {
const error = billing.declined();
return Response.json(toClientError(error, runtimeContext.requestId), { status: 402 });
}
return Response.json({ ok: true });
}, { name: "checkout" });Everything new in @autter/runtime-node 1.5.0 (runtimeContext,
RuntimeError, defineRuntimeErrors, runInBackground, initAutterLogging,
enrichers, sinks, …) is re-exported from @autter/runtime-next and
/server. @autter/runtime-next/client adds autterErrorFromResponse.
middleware.ts runs on the edge runtime — use @autter/runtime-next/edge
(re-exports @autter/runtime-edge):
import { NextResponse } from "next/server";
import { withAutter } from "@autter/runtime-next/edge";
export default withAutter(
{ apiKey: process.env.AUTTER_RUNTIME_KEY, service: "web-middleware" },
async (request, _event, _ctx, rt) => {
rt.set({ locale: request.headers.get("accept-language")?.slice(0, 2) });
return NextResponse.next();
},
);