Manual Setup
Learn how to set up the SDK manually.
If you can't (or prefer not to) run the automatic setup, you can follow the instructions below to configure your application.
Get started by installing the Sentry Remix SDK:
npm install --save @sentry/remix
To use this SDK, initialize Sentry in your Remix project for both the client and server.
entry.client.tsx
import { useLocation, useMatches } from "@remix-run/react";
import * as Sentry from "@sentry/remix";
import { useEffect } from "react";
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
integrations: [
Sentry.browserTracingIntegration({
useEffect,
useLocation,
useMatches,
}),
// Replay is only available in the client
Sentry.replayIntegration(),
],
// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for tracing.
// We recommend adjusting this value in production
tracesSampleRate: 1.0,
// Set `tracePropagationTargets` to control for which URLs distributed tracing should be enabled
tracePropagationTargets: ["localhost", /^https:\/\/yourserver\.io\/api/],
// Capture Replay for 10% of all sessions,
// plus for 100% of sessions with an error
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
});
To catch React component errors (in Remix v1) and routing transactions (in all Remix versions), wrap your Remix root with withSentry
.
If you use the Remix v2_errorBoundary
future flag, you must also configure a v2 ErrorBoundary.
root.tsx
import {
Links,
LiveReload,
Meta,
Outlet,
Scripts,
ScrollRestoration,
} from "@remix-run/react";
import { withSentry } from "@sentry/remix";
function App() {
return (
<html>
<head>
<Meta />
<Links />
</head>
<body>
<Outlet />
<ScrollRestoration />
<Scripts />
<LiveReload />
</body>
</html>
);
}
export default withSentry(App);
If you use Remix v2, wrapWithErrorBoundary
is disabled by default. You still need to wrap your root component with withSentry
to capture routing transactions.
You can disable or configure ErrorBoundary
using a second parameter to withSentry
.
withSentry(App, {
wrapWithErrorBoundary: false,
});
// or
withSentry(App, {
errorBoundaryOptions: {
fallback: <p>An error has occurred</p>,
},
});
Create an instrumentation file (named here as instrument.server.mjs
) in your project. Add your initialization code in this file for the server-side SDK.
instrument.server.mjs
import * as Sentry from "@sentry/remix";
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for tracing.
// We recommend adjusting this value in production
tracesSampleRate: 1.0,
// To use Sentry OpenTelemetry auto-instrumentation
// default: false
autoInstrumentRemix: true,
// Optionally capture action formData attributes with errors.
// This requires `sendDefaultPii` set to true as well.
captureActionFormDataKeys: {
key_x: true,
key_y: true,
},
// To capture action formData attributes.
sendDefaultPii: true
});
Then run your Remix server with:
NODE_OPTIONS='--import=./instrument.server.mjs' remix-serve build
# or
NODE_OPTIONS='--require=./instrument.server.cjs' remix-serve build
If you use the Express server instead of the Remix built-in server, you can alternatively import your instrumentation file directly at the top of your server implementation. See the example here.
Sentry's Remix SDK will automatically record your action
and loader
transactions, as well as server-side errors. You can also initialize Sentry's database integrations, such as Prisma, to get spans for your database calls.
Available from SDK version 7.59.0
Remix v2 will introduce new features that require additional configuration to work with Sentry. These features are also available from version 1.17.0 with future flags.
To capture errors from v2 ErrorBoundary, you should define your own ErrorBoundary
in root.tsx
and use Sentry.captureRemixErrorBoundaryError
inside of it. You can also create route-specific error capturing behavior by defining ErrorBoundary
in your route components. The ErrorBoundary
you define in root.tsx
will be used as a fallback for all routes.
root.tsx
import { captureRemixErrorBoundaryError } from "@sentry/remix";
export const ErrorBoundary: V2_ErrorBoundaryComponent = () => {
const error = useRouteError();
captureRemixErrorBoundaryError(error);
return <div> ... </div>;
};
Sentry won't be able to capture your unexpected server-side errors automatically on Remix v2. To work around this, instrument the handleError
function in your server entry point.
If you're using Sentry Remix SDK version 7.87.0
or higher, you can use wrapHandleErrorWithSentry
to export as your handleError
function.
entry.server.tsx (@sentry/remix >= 7.87.0)
import { wrapHandleErrorWithSentry } from "@sentry/remix";
export const handleError = wrapHandleErrorWithSentry;
For SDK versions older than 7.87.0
, you can use Sentry.captureRemixServerException
to capture errors inside handleError
.
entry.server.tsx (@sentry/remix < 7.87.0)
export function handleError(
error: unknown,
{ request }: DataFunctionArgs,
): void {
if (error instanceof Error) {
Sentry.captureRemixServerException(error, "remix.server", request);
} else {
// Optionally capture non-Error objects
Sentry.captureException(error);
}
}
After you've completed this setup, the SDK will automatically capture unhandled errors and promise rejections, and monitor performance in the client. You can also manually capture errors.
You can refer to Remix Docs to learn how to use your Sentry DSN with environment variables.
To enable readable stack traces, configure source maps upload for your production builds.
You can import your server instrumentation file at the top of your Express server implementation.
server.ts
// import the Sentry instrumentation file before anything else.
import "./instrument.server.mjs";
// alternatively `require('./instrument.server.cjs')`
// ...
const app = express();
// ...
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").