Nitro
Learn how to set up Sentry in your Nitro app to capture errors and monitor performance.
This SDK is currently in BETA. Beta features are still in progress and may have bugs. Please reach out on GitHub if you have any feedback or concerns.
You need:
Choose the features you want to configure, and this guide will show you how:
Run the command for your preferred package manager to add the Sentry SDK to your application:
npm install @sentry/nitro --save
The Nitro SDK is configured in two places: a build-time wrapper that registers a Nitro module, and a runtime file that initializes the SDK before your server starts.
Wrap your Nitro config with withSentryConfig so the Sentry module is registered during the build. Provide your auth token, organization, and project slugs so that source maps are automatically uploaded during production builds.
.envSENTRY_AUTH_TOKEN=___ORG_AUTH_TOKEN___
Create an instrument.mjs file in your project root:
instrument.mjsimport * as Sentry from "@sentry/nitro";
Sentry.init({
dsn: "___PUBLIC_DSN___",
// Adds request headers and IP for users, for more info visit:
// https://docs.sentry.io/platforms/javascript/guides/nitro/configuration/options/#sendDefaultPii
sendDefaultPii: true,
// ___PRODUCT_OPTION_START___ performance
// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for tracing.
// We recommend adjusting this value in production
// Learn more at
// https://docs.sentry.io/platforms/javascript/guides/nitro/configuration/options/#tracesSampleRate
tracesSampleRate: 1.0,
// ___PRODUCT_OPTION_END___ performance
// ___PRODUCT_OPTION_START___ logs
// Enable logs to be sent to Sentry
enableLogs: true,
// ___PRODUCT_OPTION_END___ logs
});
By default, withSentryConfig generates hidden source maps, uploads them to Sentry, and deletes the .map files after the build. This gives you readable stack traces in Sentry without shipping source maps to production. If you already set sourcemap in your Nitro config, the SDK respects your setting.
Load the instrumentation file with Node's --import flag before any Nitro command. This works for nitro dev, nitro preview, and your production start script:
package.json{
"scripts": {
"dev": "NODE_OPTIONS='--import ./instrument.mjs' nitro dev",
"preview": "NODE_OPTIONS='--import ./instrument.mjs' nitro preview",
"start": "NODE_OPTIONS='--import ./instrument.mjs' node .output/server/index.mjs"
}
}
Let's test your setup and confirm that Sentry is working correctly and sending data to your Sentry project.
Add a test route that throws an error, then open /debug-sentry in your browser (or curl it) to trigger the error:
routes/debug-sentry.tsimport { defineHandler } from "nitro/h3";
export default defineHandler(() => {
throw new Error("My first Sentry error!");
});
To verify tracing, add a handler that starts a manual span:
routes/debug-sentry.tsimport { defineHandler } from "nitro/h3";
import * as Sentry from "@sentry/nitro";
export default defineHandler(async () => {
await Sentry.startSpan(
{
op: "test",
name: "My First Test Transaction",
},
async () => {
await new Promise((resolve) => setTimeout(resolve, 100));
throw new Error("My first Sentry error!");
},
);
});
To verify that Sentry catches your logs, add some log statements to your application:
Sentry.logger.info("User example action completed");
Sentry.logger.warn("Slow operation detected", {
operation: "data_fetch",
duration: 3500,
});
Sentry.logger.error("Validation failed", {
field: "email",
reason: "Invalid email",
});
Finally, head over to your project on Sentry.io to view the collected data (it takes a couple of moments for the data to appear).
The SDK registers a Nitro error hook that captures unhandled errors from route handlers and middleware. HTTPErrors with 3xx or 4xx status codes are skipped.
To disable the built-in error hook, set enableNitroErrorHandler: false in Sentry.init:
instrument.mjsSentry.init({
dsn: "___PUBLIC_DSN___",
enableNitroErrorHandler: false,
});
The SDK creates transactions for incoming requests using Nitro's tracing channels (h3.request and srvx.request). withSentryConfig enables tracingChannel: true on your Nitro config automatically.
- Root request spans use
op: 'http.server'with parameterized route names (e.g.GET /users/:id) - Middleware spans use
op: 'middleware.nitro' - Path parameters are attached as
url.path.parameter.<key>attributes - 3xx/4xx
HTTPErrors do not mark the span as errored
The SDK appends sentry-trace and baggage values to Server-Timing response headers so the browser SDK can link pageload traces to their server trace. Incoming sentry-trace and baggage headers are honored by the underlying @sentry/node SDK. No additional configuration needed.
You can create manual spans inside your route handlers:
import { defineHandler } from "nitro/h3";
import * as Sentry from "@sentry/nitro";
export default defineHandler(() => {
return Sentry.startSpan({ name: "process-payment" }, () => {
// ... your code
});
});
The SDK is a wrapper around @sentry/node and re-exports its full API. All Node.js instrumentation from @sentry/node (HTTP clients, databases, etc.) works out of the box, and the Nitro-specific tracing channels add parameterized routes and middleware spans on top.
- Explore practical guides on what to monitor, log, track, and investigate after setup
- Learn how to manually capture errors
- Continue to customize your configuration
- Get familiar with Sentry's product features like tracing, insights, and alerts
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").