Skip to content

Commit

Permalink
feat(remix): Add remixBrowserTracingIntegration
Browse files Browse the repository at this point in the history
  • Loading branch information
onurtemizkan committed Jan 31, 2024
1 parent 5fd5c5d commit fd6503a
Show file tree
Hide file tree
Showing 25 changed files with 379 additions and 80 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,7 @@ jobs:
matrix:
node: [18, 20, 21]
remix: [1, 2]
tracingIntegration: [false, true]
# Remix v2 only supports Node 18+, so run Node 14, 16 tests separately
include:
- node: 14
Expand All @@ -882,6 +883,7 @@ jobs:
env:
NODE_VERSION: ${{ matrix.node }}
REMIX_VERSION: ${{ matrix.remix }}
TRACING_INTEGRATION: ${{ matrix.tracingIntegration }}
run: |
cd packages/remix
yarn test:integration:ci
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ module.exports = {
// serverBuildPath: 'build/index.js',
// publicPath: '/build/',
serverModuleFormat: 'cjs',
entry,
};
39 changes: 21 additions & 18 deletions packages/remix/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,26 @@

## General

This package is a wrapper around `@sentry/node` for the server and `@sentry/react` for the client, with added functionality related to Remix.
This package is a wrapper around `@sentry/node` for the server and `@sentry/react` for the client, with added
functionality related to Remix.

To use this SDK, initialize Sentry in your Remix entry points for both the client and server.

```ts
// entry.client.tsx

import { useLocation, useMatches } from "@remix-run/react";
import * as Sentry from "@sentry/remix";
import { useEffect } from "react";
import { useLocation, useMatches } from '@remix-run/react';
import * as Sentry from '@sentry/remix';
import { useEffect } from 'react';

Sentry.init({
dsn: "__DSN__",
dsn: '__DSN__',
tracesSampleRate: 1,
integrations: [
new Sentry.BrowserTracing({
routingInstrumentation: Sentry.remixRouterInstrumentation(
useEffect,
useLocation,
useMatches,
),
Sentry.remixBrowserTracingIntegration({
useEffect,
useLocation,
useMatches,
}),
],
// ...
Expand All @@ -42,19 +41,20 @@ Sentry.init({
```ts
// entry.server.tsx

import { prisma } from "~/db.server";
import { prisma } from '~/db.server';

import * as Sentry from "@sentry/remix";
import * as Sentry from '@sentry/remix';

Sentry.init({
dsn: "__DSN__",
dsn: '__DSN__',
tracesSampleRate: 1,
integrations: [new Sentry.Integrations.Prisma({ client: prisma })],
// ...
});
```

Also, wrap your Remix root with `withSentry` to catch React component errors and to get parameterized router transactions.
Also, wrap your Remix root with `withSentry` to catch React component errors and to get parameterized router
transactions.

```ts
// root.tsx
Expand Down Expand Up @@ -139,8 +139,11 @@ Sentry.captureEvent({

## Sourcemaps and Releases

The Remix SDK provides a script that automatically creates a release and uploads sourcemaps. To generate sourcemaps with Remix, you need to call `remix build` with the `--sourcemap` option.
The Remix SDK provides a script that automatically creates a release and uploads sourcemaps. To generate sourcemaps with
Remix, you need to call `remix build` with the `--sourcemap` option.

On release, call `sentry-upload-sourcemaps` to upload source maps and create a release. To see more details on how to use the command, call `sentry-upload-sourcemaps --help`.
On release, call `sentry-upload-sourcemaps` to upload source maps and create a release. To see more details on how to
use the command, call `sentry-upload-sourcemaps --help`.

For more advanced configuration, [directly use `sentry-cli` to upload source maps.](https://github.com/getsentry/sentry-cli).
For more advanced configuration,
[directly use `sentry-cli` to upload source maps.](https://github.com/getsentry/sentry-cli).
5 changes: 3 additions & 2 deletions packages/remix/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,12 @@
"fix": "eslint . --format stylish --fix",
"lint": "eslint . --format stylish",
"test": "yarn test:unit",
"test:integration": "run-s test:integration:v1 test:integration:v2",
"test:integration": "run-s test:integration:v1 test:integration:v2 test:integration:tracingIntegration",
"test:integration:v1": "run-s test:integration:clean test:integration:prepare test:integration:client test:integration:server",
"test:integration:v2": "export REMIX_VERSION=2 && run-s test:integration:v1",
"test:integration:tracingIntegration": "export TRACING_INTEGRATION=true && run-s test:integration:v2",
"test:integration:ci": "run-s test:integration:clean test:integration:prepare test:integration:client:ci test:integration:server",
"test:integration:prepare": "(cd test/integration && yarn)",
"test:integration:prepare": "(cd test/integration && yarn install --force)",
"test:integration:clean": "(cd test/integration && rimraf .cache node_modules build)",
"test:integration:client": "yarn playwright install-deps && yarn playwright test test/integration/test/client/ --project='chromium'",
"test:integration:client:ci": "yarn test:integration:client --reporter='line'",
Expand Down
41 changes: 41 additions & 0 deletions packages/remix/src/client/browserTracingIntegration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { browserTracingIntegration as originalBrowserTracingIntegration } from '@sentry/react';
import type { Integration } from '@sentry/types';
import { setGlobals, startPageloadSpan } from './performance';
import type { RemixBrowserTracingIntegrationOptions } from './performance';
/**
* Creates a browser tracing integration for Remix applications.
* This integration will create pageload and navigation spans.
*/
export function remixBrowserTracingIntegration(options: RemixBrowserTracingIntegrationOptions): Integration {
if (options.startTransactionOnPageLoad === undefined) {
options.startTransactionOnPageLoad = true;
}

if (options.startTransactionOnLocationChange === undefined) {
options.startTransactionOnLocationChange = true;
}

setGlobals({
useEffect: options.useEffect,
useLocation: options.useLocation,
useMatches: options.useMatches,
startTransactionOnLocationChange: options.startTransactionOnLocationChange,
});

const browserTracingIntegrationInstance = originalBrowserTracingIntegration({
...options,
instrumentPageLoad: false,
instrumentNavigation: false,
});

return {
...browserTracingIntegrationInstance,
afterAllSetup(client) {
browserTracingIntegrationInstance.afterAllSetup?.(client);

if (options.startTransactionOnPageLoad) {
startPageloadSpan();
}
},
};
}
Loading

0 comments on commit fd6503a

Please sign in to comment.