Configuration - Next.js

3 min read Updated: 11.09.2026

On this page Environment variables
  1. Environment variables
  2. Environments
  3. Transaction names and tags
  4. What gets stripped from a report
  5. JavaScript errors from the browser
  6. Reporting by hand from the browser
  7. Vercel
  8. Protecting the private key

Environment variables

The integration has no config file of its own - everything is read from the environment when initRay() runs.

VariableDefaultMeaning
RAY_TOKEN, RAY_PRIVATE_KEY-project credentials; without both the integration stays silent
RAY_URLhttps://dockray.ioDockRay instance
RAY_ENVIRONMENTVERCEL_ENV, then NODE_ENVenvironment column in the panel
RAY_RELEASEVERCEL_GIT_COMMIT_SHAversion of the deployed application
RAY_SAMPLE_RATE1share of error events sent
RAY_TRACES_SAMPLE_RATE0share of transactions sent; 0 disables tracing
RAY_SEND_DEFAULT_PIIfalseattaches the visitor's IP address and user agent

Environments

Every environment should report under an unambiguous name - production, staging, preview. The name is a column in the panel and a filter on the error list, so without it a production outage looks exactly like an error someone triggered in a test. Leave your local environment without credentials: with no token and no key the integration loads and stays silent, so you do not need a separate switch to turn it off.

Transaction names and tags

Every report from onRequestError carries tags built from the context Next supplies: router (App or Pages), route - the route pattern, such as /orders/[id], rather than the concrete path - route_type and render_source. The route pattern is what keeps one route as one row in the panel no matter how many identifiers passed through it.

What gets stripped from a report

Before an event reaches DockRay, the integration removes Authorization, Cookie, Set-Cookie, X-Api-Key and the browser collector's own token from the headers. The visitor's IP address and user agent are attached only with RAY_SEND_DEFAULT_PII=true - without it a report carries no user field at all.

JavaScript errors from the browser

Off by default. Turning it on needs two pieces.

The route that receives them - app/api/ray/browser/route.ts:

js
import { createBrowserErrorRoute } from '@dockcodes/dock-ray-next';

export const POST = createBrowserErrorRoute();
export const runtime = 'nodejs';

The collector, mounted once in the root layout:

js
import { RayBrowserReporting } from '@dockcodes/dock-ray-next/client';

export default function RootLayout({ children }) {
    return (
        <html>
            <body>
                <RayBrowserReporting />
                {children}
            </body>
        </html>
    );
}

NEXT_PUBLIC_RAY_JS_ERRORS=true turns the collector on - the prefix is intentional here, because the field only carries a flag, not a secret.

The browser reports to your route, never directly to the panel: authenticating needs the project's private key, and a key inside the client bundle is a published key. Your server forwards every report with its own key and fills in the envelope - id, timestamp, environment, release - so the browser never chooses which environment its errors land in.

The route answers 202 to everything - a valid report, a malformed one, one rejected by the rate limit - so a caller learns nothing about the guards. It drops bodies over 16 KB and allows twenty reports per address per minute. The browser-side collector caps itself too: one report per distinct error per page view, ten per page view by default, with ResizeObserver loop and cross-origin Script error. filtered out.

Reporting by hand from the browser

js
'use client';
import { captureBrowserException } from '@dockcodes/dock-ray-next/client';

export default function GlobalError({ error }) {
    captureBrowserException(error);

    return <html><body><h1>Something went wrong</h1></body></html>;
}

Vercel

When RAY_ENVIRONMENT and RAY_RELEASE are not set, the integration takes VERCEL_ENV as the environment and VERCEL_GIT_COMMIT_SHA as the release, so a preview deployment does not report as production.

Protecting the private key

The private key is a project secret, not an identifier. Keep it in environment variables, in a secrets manager or in the server configuration - never in the repository, in logs, in a screenshot or in code sent to the browser. One project can hold many keys, so production and staging should each get their own: either can be revoked on its own without interrupting the others. A suspicion that a key leaked is reason enough to revoke it and generate a new one.

Keep reading

DockRay newsletter

Application security in your inbox

Important vulnerabilities, actionable guidance and practical advice for your applications. Choose your technologies and follow what matters to your project.

  • A daily digest of new vulnerabilities, critical ones included.
  • Notifications about important updates.
  • Practical advice on application security and monitoring.

Leave empty to receive updates for every technology.

Free to subscribe. Unsubscribe with one click in any email.