new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Next.js · Guides · all subjects

building/instrumentation

35 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

register function requirements

Export a register function in the instrumentation file. This function will be called exactly once when a new Next.js server instance is initiated, and must complete before the server is ready to handle requests.

What instrumentation is

Instrumentation is the process of using code to integrate monitoring and logging tools into your application. It allows you to track the performance and behavior of your application, and to debug issues in production.

Instrumentation with OpenTelemetry example

Example of setting up Next.js with OpenTelemetry using @vercel/otel: ```ts filename="instrumentation.ts" import { registerOTel } from '@vercel/otel' export function register() { registerOTel('next-app') } ```

Importing files with side effects in register

You can import files with side effects within the register function using JavaScript import syntax. This allows you to access global variables defined by packages without explicitly using them in your code. It is recommended to import files from within the register function rather than at the top of the file to colocate all side effects in one place and avoid unintended consequences.

Importing files with side effects example

Example of importing a package with side effects in the register function: ```ts filename="instrumentation.ts" export async function register() { await import('package-with-side-effect') } ```

Using NEXT_RUNTIME to conditionally import code

Next.js calls register in all environments, so conditionally import code that doesn't support specific runtimes using the NEXT_RUNTIME environment variable. This variable can be set to 'nodejs' or 'edge' to determine the current runtime environment.

Conditional runtime-specific imports example

Example of conditionally importing runtime-specific code based on NEXT_RUNTIME: ```ts filename="instrumentation.ts" export async function register() { if (process.env.NEXT_RUNTIME === 'nodejs') { await import('./instrumentation-node') } if (process.env.NEXT_RUNTIME === 'edge') { await import('./instrumentation-edge') } } ```

Install packages for @vercel/otel setup

To get started with OpenTelemetry using @vercel/otel, install these packages: @vercel/otel, @opentelemetry/sdk-logs, @opentelemetry/api-logs, and @opentelemetry/instrumentation. Use pnpm add, npm install, yarn add, or bun add depending on your package manager.

Create instrumentation.ts file location

The instrumentation.ts (or .js) file should be created in the root directory of the project, or inside the src folder if using one. It should not be inside the app or pages directory. If using the pageExtensions config option, update the instrumentation filename to match.

Basic @vercel/otel registration code

Create an instrumentation.ts file with a register function that imports and calls registerOTel with a serviceName parameter: import { registerOTel } from '@vercel/otel'; export function register() { registerOTel({ serviceName: 'next-app' }) }

Manual OpenTelemetry configuration packages

For manual OpenTelemetry configuration, install: @opentelemetry/sdk-node, @opentelemetry/resources, @opentelemetry/semantic-conventions, @opentelemetry/sdk-trace-node, and @opentelemetry/exporter-trace-otlp-http.

NodeSDK not compatible with edge runtime

NodeSDK is not compatible with edge runtime. When using manual OpenTelemetry configuration, create a separate instrumentation.node.ts file and conditionally import it only when process.env.NEXT_RUNTIME === 'nodejs' to ensure edge runtime compatibility.

Manual NodeSDK initialization example

When manually initializing NodeSDK, import OTLPTraceExporter, resourceFromAttributes, NodeSDK, SimpleSpanProcessor, and ATTR_SERVICE_NAME. Create a new NodeSDK instance with a resource configured with ATTR_SERVICE_NAME, add a SimpleSpanProcessor with OTLPTraceExporter, and call sdk.start().

Enable verbose OpenTelemetry tracing

To see more spans than are emitted by default in Next.js, set the environment variable NEXT_OTEL_VERBOSE=1.

Custom OpenTelemetry exporters without collector

You do not need an OpenTelemetry Collector. You can use a custom OpenTelemetry exporter with @vercel/otel or manual OpenTelemetry configuration.

Install @opentelemetry/api for custom spans

To create custom spans with OpenTelemetry APIs, install the @opentelemetry/api package using your package manager (pnpm add, npm install, yarn add, or bun add).

Create custom span example

To create a custom span, import trace from @opentelemetry/api, then use trace.getTracer('tracer-name').startActiveSpan('span-name', async (span) => { ... }) to wrap your code. Call span.end() in a finally block to ensure the span is properly closed.

Register function execution timing

The register function in instrumentation.ts executes before your code runs in a new environment. Custom spans created within it will be correctly added to the exported trace.

Next.js custom span attributes in namespace 'next'

Next.js adds custom attributes to spans under the 'next' namespace: next.span_name (duplicates span name), next.span_type (unique identifier for span type), next.route (route pattern like /[param]/user), next.rsc (true/false indicating RSC request), and next.page (internal app router value used as unique identifier when paired with next.route).

HTTP request root span attributes

The root span for each incoming request to Next.js is labeled '[http.method] [next.route]' with span_type 'BaseServer.handleRequest'. It includes attributes: http.method, http.status_code, http.route, http.target, next.span_name, next.span_type, and next.route.

App router rendering span attributes

The 'render route (app) [next.route]' span with span_type 'AppRender.getBodyResult' represents the process of rendering a route in the app router. It includes attributes: next.span_name, next.span_type, and next.route.

Fetch request span attributes

The 'fetch [http.method] [http.url]' span with span_type 'AppRender.fetch' represents a fetch request executed in your code. It includes common HTTP attributes (http.method), client HTTP attributes (http.url, net.peer.name, net.peer.port if specified), next.span_name, and next.span_type.

Disable fetch span instrumentation

The fetch span can be turned off by setting NEXT_OTEL_FETCH_DISABLED=1 in your environment. This is useful when you want to use a custom fetch instrumentation library.

API route handler span attributes

The 'executing api route (app) [next.route]' span with span_type 'AppRouteRouteHandlers.runHandler' represents the execution of an API Route Handler in the app router. It includes attributes: next.span_name, next.span_type, and next.route.

getServerSideProps span attributes

The 'getServerSideProps [next.route]' span with span_type 'Render.getServerSideProps' represents the execution of getServerSideProps for a specific route. It includes attributes: next.span_name, next.span_type, and next.route.

getStaticProps span attributes

The 'getStaticProps [next.route]' span with span_type 'Render.getStaticProps' represents the execution of getStaticProps for a specific route. It includes attributes: next.span_name, next.span_type, and next.route.

Pages router document rendering span attributes

The 'render route (pages) [next.route]' span with span_type 'Render.renderDocument' represents the process of rendering the document for a specific route in pages router. It includes attributes: next.span_name, next.span_type, and next.route.

generateMetadata span attributes

The 'generateMetadata [next.page]' span with span_type 'ResolveMetadata.generateMetadata' represents the process of generating metadata for a specific page. A single route can have multiple of these spans. It includes attributes: next.span_name, next.span_type, and next.page.

Resolve page components span attributes

The 'resolve page components' span with span_type 'NextNodeServer.findPageComponents' represents the process of resolving page components for a specific page. It includes attributes: next.span_name, next.span_type, and next.route.

Resolve segment modules span attributes

The 'resolve segment modules' span with span_type 'NextNodeServer.getLayoutOrPageModule' represents loading of code modules for a layout or a page. It includes attributes: next.span_name, next.span_type, and next.segment.

Start response span meaning

The 'start response' span with span_type 'NextNodeServer.startResponse' is a zero-length span that represents the time when the first byte has been sent in the response.

OpenTelemetry recommended for Next.js applications

OpenTelemetry is recommended for instrumenting Next.js applications. It is a platform-agnostic way to instrument apps that allows you to change your observability provider without changing your code. Next.js supports OpenTelemetry instrumentation out of the box with Next.js already instrumented.

Error code transformation via SWC plugin

The Next.js SWC plugin transforms Error constructors by rewriting 'new Error' or 'Error' to include an additional property: Object.defineProperty(new Error(...), '__NEXT_ERROR_CODE', { value: $code, enumerable: false, configurable: true }). The enumerable: false ensures the error code won't show up in console logs while still being accessible for telemetry. The configurable: true ensures the error code can be overwritten, useful for transforming errors. This enables anonymous error code reporting for user feedback while keeping the message private.

Error code mapping file location and structure

Error code mappings are stored in packages/next/errors.json. The file uses an append-only, increment-based structure that maps error codes to messages.

Automatic errors.json update on build

Running 'pnpm build' automatically updates errors.json if new errors are introduced. The updated errors.json file must always be committed to avoid CI failures.

Give your agent this brain