Configuration - Next.js
Environment variables
The integration has no config file of its own - everything is read from the environment when initRay() runs.
| Variable | Default | Meaning |
|---|---|---|
RAY_TOKEN, RAY_PRIVATE_KEY | - | project credentials; without both the integration stays silent |
RAY_URL | https://dockray.io | DockRay instance |
RAY_ENVIRONMENT | VERCEL_ENV, then NODE_ENV | environment column in the panel |
RAY_RELEASE | VERCEL_GIT_COMMIT_SHA | version of the deployed application |
RAY_SAMPLE_RATE | 1 | share of error events sent |
RAY_TRACES_SAMPLE_RATE | 0 | share of transactions sent; 0 disables tracing |
RAY_SEND_DEFAULT_PII | false | attaches 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:
import { createBrowserErrorRoute } from '@dockcodes/dock-ray-next';
export const POST = createBrowserErrorRoute();
export const runtime = 'nodejs';
The collector, mounted once in the root layout:
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
'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.