Skip to content

Commit 3669f91

Browse files
feat: Next.js SDK + Plugin (#3301)
1 parent 41a68a0 commit 3669f91

28 files changed

+1361
-25
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ package. Please refer to the README and instructions of those SDKs for more deta
4848
- [`@sentry/ember`](https://github.com/getsentry/sentry-javascript/tree/master/packages/ember): browser SDK with Ember integration enabled
4949
- [`@sentry/vue`](https://github.com/getsentry/sentry-javascript/tree/master/packages/vue): browser SDK with Vue integration enabled
5050
- [`@sentry/gatsby`](https://github.com/getsentry/sentry-javascript/tree/master/packages/gatsby): SDK for Gatsby
51+
- [`@sentry/nextjs`](https://github.com/getsentry/sentry-javascript/tree/master/packages/nextjs): SDK for Next.js
5152
- [`@sentry/react-native`](https://github.com/getsentry/sentry-react-native): SDK for React Native with support for native crashes
5253
- [`@sentry/integrations`](https://github.com/getsentry/sentry-javascript/tree/master/packages/integrations): Pluggable
5354
integrations that can be used to enhance JS SDKs

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
"packages/hub",
3030
"packages/integrations",
3131
"packages/minimal",
32+
"packages/nextjs",
33+
"packages/next-plugin-sentry",
3234
"packages/node",
3335
"packages/react",
3436
"packages/serverless",

packages/next-plugin-sentry/LICENSE

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
MIT License
2+
3+
Copyright (c) 2021, Sentry
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
* Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
* Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
* Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

packages/next-plugin-sentry/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<p align="center">
2+
<a href="https://sentry.io" target="_blank" align="center">
3+
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280">
4+
</a>
5+
<br />
6+
</p>
7+
8+
# Official Sentry plugin for Next.js
9+
10+
## Links
11+
12+
- [Official SDK Docs](https://docs.sentry.io/platforms/javascript/guides/nextjs/)
13+
- [TypeDoc](http://getsentry.github.io/sentry-javascript/)
14+
15+
## Usage
16+
17+
You don't have to interact with this plugin to use Sentry with your application, see [`@sentry/nextjs`](https://github.com/getsentry/sentry-javascript/tree/master/packages/nextjs) instead.

packages/next-plugin-sentry/env.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export const getDsn = () =>
2+
process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;
3+
4+
export const getRelease = () =>
5+
process.env.SENTRY_RELEASE ||
6+
process.env.NEXT_PUBLIC_SENTRY_RELEASE ||
7+
process.env.VERCEL_GITHUB_COMMIT_SHA ||
8+
process.env.VERCEL_GITLAB_COMMIT_SHA ||
9+
process.env.VERCEL_BITBUCKET_COMMIT_SHA;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "@sentry/next-plugin-sentry",
3+
"version": "6.2.5",
4+
"description": "Sentry plugin for Next.js, part of the @sentry/nextjs SDK",
5+
"repository": "git://github.com/getsentry/sentry-javascript.git",
6+
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/next-plugin-sentry",
7+
"author": "Sentry",
8+
"license": "MIT",
9+
"engines": {
10+
"node": ">=6"
11+
},
12+
"main": "index.js",
13+
"publishConfig": {
14+
"access": "public"
15+
},
16+
"dependencies": {
17+
"@sentry/nextjs": "6.2.5",
18+
"@sentry/integrations": "6.2.5"
19+
},
20+
"devDependencies": {
21+
"eslint": "7.20.0",
22+
"rimraf": "3.0.2"
23+
},
24+
"nextjs": {
25+
"name": "sentry",
26+
"required-env": []
27+
},
28+
"peerDependencies": {
29+
"next": "*"
30+
},
31+
"scripts": {
32+
"link:yarn": "yarn link",
33+
"pack": "npm pack"
34+
},
35+
"volta": {
36+
"extends": "../../package.json"
37+
}
38+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { withScope, captureException, captureMessage } from '@sentry/nextjs';
2+
3+
export default async function onErrorClient({ err }) {
4+
withScope(scope => {
5+
if (err instanceof Error) {
6+
captureException(err);
7+
} else {
8+
captureMessage(err.message);
9+
}
10+
});
11+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { captureException, flush, Handlers, withScope } from '@sentry/nextjs';
2+
import getConfig from 'next/config';
3+
4+
const { parseRequest } = Handlers;
5+
6+
export default async function onErrorServer(err) {
7+
const { serverRuntimeConfig = {}, publicRuntimeConfig = {} } = getConfig() || {};
8+
const sentryTimeout = serverRuntimeConfig.sentryTimeout || publicRuntimeConfig.sentryTimeout || 2000;
9+
10+
withScope(scope => {
11+
if (err.req) {
12+
scope.addEventProcessor(event => {
13+
return parseRequest(event, err.req, {
14+
// 'cookies' and 'query_string' use `dynamicRequire` which has a bug in SSR envs right now — Kamil
15+
request: ['data', 'headers', 'method', 'url'],
16+
});
17+
});
18+
}
19+
20+
const toCapture = err instanceof Error ? err : err.err;
21+
22+
scope.addEventProcessor((event, hint) => {
23+
if (hint.originalException === toCapture) {
24+
event.exception.values[0].mechanism = {
25+
handled: false,
26+
type: 'onErrorServer',
27+
};
28+
}
29+
return event;
30+
});
31+
32+
captureException(toCapture);
33+
});
34+
35+
await flush(sentryTimeout);
36+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import '../../../../sentry.client.config.js';
2+
3+
export default async function initClient() {
4+
// There is no initialization code. The goal of this file is the
5+
// side-effect of importing the`sentry.client.config.js` file.
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import '../../../../sentry.server.config.js';
2+
3+
export default async function initServer() {
4+
// There is no initialization code. The goal of this file is the
5+
// side-effect of importing the`sentry.server.config.js` file.
6+
}

packages/nextjs/.eslintrc.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
module.exports = {
2+
root: true,
3+
env: {
4+
es6: true,
5+
browser: true,
6+
node: true,
7+
},
8+
parserOptions: {
9+
ecmaVersion: 2018,
10+
},
11+
extends: ['@sentry-internal/sdk'],
12+
ignorePatterns: ['build/**', 'dist/**', 'esm/**', 'examples/**', 'scripts/**'],
13+
overrides: [
14+
{
15+
files: ['*.ts', '*.tsx', '*.d.ts'],
16+
parserOptions: {
17+
project: './tsconfig.json',
18+
},
19+
},
20+
{
21+
files: ['test/**'],
22+
rules: {
23+
'@typescript-eslint/no-explicit-any': 'off',
24+
'@typescript-eslint/no-non-null-assertion': 'off',
25+
},
26+
},
27+
],
28+
rules: {
29+
'max-lines': 'off',
30+
'@sentry-internal/sdk/no-async-await': 'off',
31+
'jsdoc/require-jsdoc': 0,
32+
},
33+
};

packages/nextjs/LICENSE

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
MIT License
2+
3+
Copyright (c) 2021, Sentry
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
* Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
* Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
* Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

packages/nextjs/README.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<p align="center">
2+
<a href="https://sentry.io" target="_blank" align="center">
3+
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280">
4+
</a>
5+
<br />
6+
</p>
7+
8+
# Official Sentry SDK for Next.js
9+
10+
[![npm version](https://img.shields.io/npm/v/@sentry/nextjs.svg)](https://www.npmjs.com/package/@sentry/nextjs)
11+
[![npm dm](https://img.shields.io/npm/dm/@sentry/nextjs.svg)](https://www.npmjs.com/package/@sentry/nextjs)
12+
[![npm dt](https://img.shields.io/npm/dt/@sentry/nextjs.svg)](https://www.npmjs.com/package/@sentry/nextjs)
13+
[![typedoc](https://img.shields.io/badge/docs-typedoc-blue.svg)](http://getsentry.github.io/sentry-javascript/)
14+
15+
## Links
16+
17+
- [Official SDK Docs](https://docs.sentry.io/platforms/javascript/guides/nextjs/)
18+
- [TypeDoc](http://getsentry.github.io/sentry-javascript/)
19+
20+
## General
21+
22+
This package is a wrapper around `@sentry/node` for the server and `@sentry/react` for the client, with added functionality related to Next.js.
23+
24+
To use this SDK, init it in the Sentry config files.
25+
26+
```javascript
27+
// sentry.client.config.js
28+
29+
import * as Sentry from '@sentry/nextjs';
30+
31+
Sentry.init({
32+
dsn: "__DSN__",
33+
// ...
34+
});
35+
```
36+
37+
```javascript
38+
// sentry.server.config.js
39+
40+
import * as Sentry from '@sentry/nextjs';
41+
42+
Sentry.init({
43+
dsn: "__DSN__",
44+
// ...
45+
});
46+
```
47+
48+
To set context information or send manual events, use the exported functions of `@sentry/nextjs`.
49+
50+
```javascript
51+
import * as Sentry from '@sentry/nextjs';
52+
53+
// Set user information, as well as tags and further extras
54+
Sentry.configureScope(scope => {
55+
scope.setExtra('battery', 0.7);
56+
scope.setTag('user_mode', 'admin');
57+
scope.setUser({ id: '4711' });
58+
// scope.clear();
59+
});
60+
61+
// Add a breadcrumb for future events
62+
Sentry.addBreadcrumb({
63+
message: 'My Breadcrumb',
64+
// ...
65+
});
66+
67+
// Capture exceptions, messages or manual events
68+
Sentry.captureMessage('Hello, world!');
69+
Sentry.captureException(new Error('Good bye'));
70+
Sentry.captureEvent({
71+
message: 'Manual',
72+
stacktrace: [
73+
// ...
74+
],
75+
});
76+
```

packages/nextjs/package.json

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{
2+
"name": "@sentry/nextjs",
3+
"version": "6.2.5",
4+
"description": "Official Sentry SDK for Next.js",
5+
"repository": "git://github.com/getsentry/sentry-javascript.git",
6+
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nextjs",
7+
"author": "Sentry",
8+
"license": "MIT",
9+
"engines": {
10+
"node": ">=6"
11+
},
12+
"main": "./dist/index.server.js",
13+
"module": "./esm/index.server.js",
14+
"browser": "./esm/index.client.js",
15+
"types": "./esm/index.client.d.ts",
16+
"publishConfig": {
17+
"access": "public"
18+
},
19+
"dependencies": {
20+
"@sentry/core": "6.2.5",
21+
"@sentry/integrations": "6.2.5",
22+
"@sentry/next-plugin-sentry": "6.2.5",
23+
"@sentry/node": "6.2.5",
24+
"@sentry/react": "6.2.5",
25+
"@sentry/utils": "6.2.5",
26+
"@sentry/webpack-plugin": "1.15.0"
27+
},
28+
"devDependencies": {
29+
"@sentry/types": "6.2.5",
30+
"@types/webpack": "^5.28.0",
31+
"eslint": "7.20.0",
32+
"rimraf": "3.0.2"
33+
},
34+
"scripts": {
35+
"build": "run-p build:esm build:es5",
36+
"build:esm": "tsc -p tsconfig.esm.json",
37+
"build:es5": "tsc -p tsconfig.build.json",
38+
"build:watch": "run-p build:watch:esm build:watch:es5",
39+
"build:watch:esm": "tsc -p tsconfig.esm.json -w --preserveWatchOutput",
40+
"build:watch:es5": "tsc -p tsconfig.build.json -w --preserveWatchOutput",
41+
"clean": "rimraf dist esm coverage *.js *.js.map *.d.ts",
42+
"link:yarn": "yarn link",
43+
"lint": "run-s lint:prettier lint:eslint",
44+
"lint:prettier": "prettier --check \"{src,test}/**/*.ts\"",
45+
"lint:eslint": "eslint . --cache --cache-location '../../eslintcache/' --format stylish",
46+
"fix": "run-s fix:eslint fix:prettier",
47+
"fix:eslint": "eslint . --format stylish --fix",
48+
"fix:prettier": "prettier --write \"{src,test}/**/*.ts\"",
49+
"test": "jest",
50+
"test:watch": "jest --watch",
51+
"pack": "npm pack"
52+
},
53+
"volta": {
54+
"extends": "../../package.json"
55+
},
56+
"jest": {
57+
"collectCoverage": true,
58+
"transform": {
59+
"^.+\\.ts$": "ts-jest"
60+
},
61+
"moduleFileExtensions": [
62+
"js",
63+
"ts"
64+
],
65+
"testEnvironment": "node",
66+
"testMatch": [
67+
"**/*.test.ts"
68+
],
69+
"globals": {
70+
"ts-jest": {
71+
"tsConfig": "./tsconfig.json",
72+
"diagnostics": false
73+
}
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)