Skip to main content
Limelight runs on Node.js servers too. Add the middleware to capture every incoming request and response — with headers, bodies, status codes, and timing — and view them alongside your client-side data. When you have Limelight on both the client and server, requests are automatically traced end-to-end using a shared trace ID.

Installation

npm install @getlimelight/sdk

Connect

Initialize Limelight in your server’s entry point, before setting up routes:
import { Limelight } from "@getlimelight/sdk";

Limelight.connect({
  platform: "node",

  // Optional: only required for hosted dashboard
  projectKey: "your-project-key",
});

Express / Connect

Use Limelight.middleware() to capture all incoming requests. Place it after body-parser middleware so request bodies are available:
import express from "express";
import { Limelight } from "@getlimelight/sdk";

Limelight.connect({ platform: "node" });

const app = express();

// Body parser first
app.use(express.json());

// Limelight middleware second
app.use(Limelight.middleware());

app.get("/api/users", (req, res) => {
  res.json({ users: [] });
});

app.listen(3000);

Middleware Options

app.use(
  Limelight.middleware({
    maxBodySize: 128 * 1024, // Capture up to 128KB of body (default: 64KB)
  })
);
OptionTypeDefaultDescription
maxBodySizenumber65536 (64KB)Maximum request/response body size to capture in bytes. Bodies exceeding this limit are truncated.

Next.js Pages Router

For Next.js Pages Router API routes (pages/api/), wrap your handler with Limelight.withLimelight():
// lib/limelight.ts
import { Limelight } from "@getlimelight/sdk";

Limelight.connect({ platform: "node" });

export { Limelight };
// pages/api/users.ts
import { Limelight } from "../../lib/limelight";

export default Limelight.withLimelight((req, res) => {
  res.status(200).json({ users: [] });
});
withLimelight works with Pages Router API routes (pages/api/) which use the Node.js (req, res) signature. It does not work with App Router route handlers (app/api/) which use the Web Standard Request/Response objects. App Router support is coming soon.

Full-Stack Tracing

When Limelight is installed on both your client and server, requests are automatically correlated using a trace header. How it works:
  1. The client SDK attaches an x-limelight-trace-id header to every outgoing request
  2. The server middleware reads this header and links the incoming request to the same trace
  3. Limelight groups both sides together in the UI so you can see the full request lifecycle
No extra configuration is needed — this works automatically.

Custom Trace Header

If x-limelight-trace-id conflicts with your infrastructure, you can customize the header name. Set the same name on both client and server:
// Client
Limelight.connect({
  traceHeaderName: "x-my-trace-id",
});

// Server
Limelight.connect({
  platform: "node",
  traceHeaderName: "x-my-trace-id",
});

Configuration

All standard Limelight.connect() options work on the server. The most relevant ones for server-side usage:
Limelight.connect({
  // Identifies this as a Node.js app
  platform: "node",

  // Optional: required for hosted dashboard
  projectKey: "your-project-key",

  // Optional: only enable in development
  enabled: process.env.NODE_ENV === "development",

  // Optional: name your server in the dashboard
  appName: "api-server",

  // Optional: skip capturing request/response bodies
  disableBodyCapture: false,

  // Optional: filter or modify events before sending
  beforeSend: (event) => {
    // Drop health check requests
    if (event.url?.includes("/health")) {
      return null;
    }
    return event;
  },
});

Security

Limelight automatically redacts sensitive headers (like authorization, cookie, and set-cookie) from captured data. You can further control what gets captured:
  • Use disableBodyCapture: true to skip all request/response bodies
  • Use beforeSend to filter out specific routes or redact fields
  • Use maxBodySize on the middleware to limit how much body data is captured
Limelight.connect({
  platform: "node",
  beforeSend: (event) => {
    // Don't capture payment endpoints
    if (event.url?.includes("/api/payments")) {
      return null;
    }
    return event;
  },
});

Verify It’s Working

Once connected, make a request to your server and check the Limelight desktop app or dashboard. You should see:
  • The incoming request with method, URL, headers, and body
  • The outgoing response with status code, headers, body, and duration
  • If the client SDK is also connected, both sides linked under the same trace ID