Skip to contentOutRay/Docs
GitHub ↗
Get started ↗
Documentation

Your services, from local to live.

OutRay documentation

Products

ObservabilityConnect your first serviceFramework SDK setupServices and healthInvestigate requests and tracesLogs and metricsConfigure alerts

SDKs & integrations

Node.js SDKTanStack Start SDKNext.js PluginExpress PluginNestJS PluginHono SDK
Observability

Next.js Plugin

Use development tunnels and configure server-side Next.js telemetry independently.

@outray/next provides a development tunnel wrapper, server-side observability initialization, and App Router request instrumentation. These are separate integrations: a tunnel is not required to export telemetry.

Install

npm install @outray/next

The package declares compatibility with Next.js 13–16. Its observability dependency requires Node.js 20 or later; use the runtime supported by your Next.js version.

Development tunnel

In next.config.ts:

import withOutray from "@outray/next";

export default withOutray(
  {},
  {
    apiKey: process.env.OUTRAY_API_KEY,
    subdomain: "my-app",
  },
);

Use a token with tunnel:connect. Run your normal next dev command and copy the URL printed by OutRay.

The wrapper starts only when NODE_ENV === "development". It starts from config loading, not a webpack hook, and reads PORT to determine the target port (default 3000). For a different port, set PORT as well as the port used by Next.js.

Tunnel optionDefaultBehavior
apiKeyOUTRAY_API_KEYTunnel credential; no CLI-login fallback
subdomainOUTRAY_SUBDOMAINRequested subdomain
customDomainUnsetVerified custom tunnel hostname
serverUrlOUTRAY_SERVER_URL or wss://connect.outray.co/Tunnel server
enabledOUTRAY_ENABLED !== "false"Enable development tunnel
silentfalseSuppress tunnel status output
localfalseAlso provide mDNS LAN access

Callbacks include onTunnelReady(url), onError(error), onClose(), onReconnecting(), and onLocalReady(info).

Initialize observability

Use Next.js's server instrumentation hook. In instrumentation.ts (or src/instrumentation.ts when your application uses src):

export async function register() {
  if (process.env.NEXT_RUNTIME !== "nodejs") return;

  const { registerOutrayObservability } =
    await import("@outray/next/observability");

  const telemetry = registerOutrayObservability({
    apiKey: process.env.OBSERVABILITY_TOKEN,
    serviceName: "storefront",
    environment: process.env.NODE_ENV,
    captureConsole: true,
  });

  telemetry.info("observability started");
}

Use a token with observability:write (Send telemetry), supplied from server-only configuration. Do not use NEXT_PUBLIC_* variables for the credential.

The runtime check and dynamic import keep the Node.js SDK out of edge runtimes. The configuration wrapper alone does not initialize this telemetry integration.

Instrument App Router handlers

// app/api/orders/route.ts
import { withOutrayRequest } from "@outray/next";

export const POST = withOutrayRequest(
  async (request: Request) => {
    const order = await request.json();
    return Response.json({ accepted: true, itemCount: order.items.length });
  },
  {
    routeResolver: () => "/api/orders",
    capturePayloads: {
      maxBodyBytes: 16 * 1024,
      redactedFields: ["accountPin"],
    },
  },
);

The wrapper records route-aware spans, response status, failures, and HTTP request count, duration, and active-request metrics. It reuses a recording server span when one exists, or creates one through the configured provider.

routeResolver supplies a stable route template; otherwise common identifier segments are normalized to :id. ignore can skip additional requests. Common Next.js asset paths are ignored by default.

Payload capture is disabled by default. When enabled, eligible JSON and URL-encoded payloads are bounded and common sensitive fields and headers are redacted. Capture inspects clones rather than consuming or replacing the handler's original Request/Response.

withOutrayPayloadCapture(handler, options) is a shortcut for request instrumentation with capture enabled. These wrappers are for App Router handlers returning a Response, not Pages Router API handlers.

Application logs and spans

import { outray, withOutraySpan } from "@outray/next/observability";

outray.info("order accepted", { orderId: "order_123" });
await withOutraySpan("process order", async () => {
  // Perform the operation here.
});

Structured logging preserves local output and can correlate logs with the active trace. Console capture is separately opt-in via captureConsole.

See the Node.js SDK for shared configuration, export timing, payload privacy, and shutdown behavior.

TanStack Start SDK

Instrument the TanStack Start Node server entry with traces, logs, and metrics.

Express Plugin

Register Express request telemetry and optionally open a development tunnel.

On this page

InstallDevelopment tunnelInitialize observabilityInstrument App Router handlersApplication logs and spans