Skip to content

Commit 6c631ca

Browse files
committed
feat(nuxt): Add piniaIntegration
1 parent 5a5b512 commit 6c631ca

File tree

6 files changed

+65
-49
lines changed

6 files changed

+65
-49
lines changed

CHANGELOG.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,29 @@
1010

1111
- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott
1212

13-
## 8.36.0
14-
15-
### Important Changes
16-
17-
- **feat(nuxt): Add Sentry Pinia plugin ([#14047](https://github.com/getsentry/sentry-javascript/pull/14047))**
13+
- **feat(nuxt): Add Sentry Pinia plugin**
1814

19-
The Nuxt SDK now allows you to track Pinia state for captured errors. To enable the Pinia plugin, set the `trackPinia` option to `true` in your client config:
15+
The Nuxt SDK now allows you to track Pinia state for captured errors. To enable the Pinia plugin, add the `piniaIntegration` to your client config:
2016

2117
```ts
2218
// sentry.client.config.ts
19+
import { usePinia } from '#imports';
2320

2421
Sentry.init({
25-
trackPinia: true,
22+
integrations: [
23+
Sentry.piniaIntegration(usePinia(), {
24+
/* optinal Pinia plugin options */
25+
}),
26+
],
2627
});
2728
```
2829

2930
Read more about the Pinia plugin in the [Sentry Pinia Documentation](https://docs.sentry.io/platforms/javascript/guides/nuxt/features/pinia/).
3031

32+
## 8.36.0
33+
34+
### Important Changes
35+
3136
- **feat(nextjs/vercel-edge/cloudflare): Switch to OTEL for performance monitoring ([#13889](https://github.com/getsentry/sentry-javascript/pull/13889))**
3237

3338
With this release, the Sentry Next.js, and Cloudflare SDKs will now capture performance data based on OpenTelemetry.
Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import * as Sentry from '@sentry/nuxt';
2-
import { useRuntimeConfig } from '#imports';
2+
import { usePinia, useRuntimeConfig } from '#imports';
33

44
Sentry.init({
55
environment: 'qa', // dynamic sampling bias to keep transactions
66
dsn: useRuntimeConfig().public.sentry.dsn,
77
tunnel: `http://localhost:3031/`, // proxy server
88
tracesSampleRate: 1.0,
99
trackComponents: true,
10-
trackPinia: {
11-
actionTransformer: action => `Transformed: ${action}`,
12-
stateTransformer: state => ({
13-
transformed: true,
14-
...state,
10+
integrations: [
11+
Sentry.piniaIntegration(usePinia(), {
12+
actionTransformer: action => `Transformed: ${action}`,
13+
stateTransformer: state => ({
14+
transformed: true,
15+
...state,
16+
}),
1517
}),
16-
},
18+
],
1719
});

packages/nuxt/src/client/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from '@sentry/vue';
22

33
export { init } from './sdk';
4+
export { piniaIntegration } from './piniaIntegration';
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { defineIntegration } from '@sentry/core';
2+
import type { IntegrationFn } from '@sentry/types';
3+
4+
import { consoleSandbox } from '@sentry/utils';
5+
import { createSentryPiniaPlugin } from '@sentry/vue';
6+
7+
const INTEGRATION_NAME = 'LinkedErrors';
8+
9+
type Pinia = { use: (plugin: ReturnType<typeof createSentryPiniaPlugin>) => void }
10+
11+
const _piniaIntegration = ((
12+
// `unknown` here as well because usePinia declares this type: `export declare const usePinia: () => unknown;`
13+
pinia: unknown | Pinia,
14+
options: Parameters<typeof createSentryPiniaPlugin>[0] = {},
15+
) => {
16+
return {
17+
name: INTEGRATION_NAME,
18+
setup() {
19+
if (!pinia || (typeof pinia === 'object' && !('use' in pinia))) {
20+
consoleSandbox(() => {
21+
// eslint-disable-next-line no-console
22+
console.warn(
23+
'[Sentry] You added the Pinia integration, but the passed parameter `pinia` has the wrong value. Make sure to enable Pinia by adding `"@pinia/nuxt"` to your Nuxt modules array and pass pinia to Sentry with `piniaIntegration(usePinia())`. Current value of `pinia`: ', pinia,
24+
);
25+
});
26+
} else {
27+
(pinia as Pinia).use(createSentryPiniaPlugin(options));
28+
}
29+
},
30+
};
31+
}) satisfies IntegrationFn;
32+
33+
/**
34+
* Monitor an existing Pinia store.
35+
*
36+
* This only works if "@pinia/nuxt" is added to the `modules` array.
37+
*/
38+
export const piniaIntegration = defineIntegration(_piniaIntegration);

packages/nuxt/src/common/types.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,10 @@
11
import type { init as initNode } from '@sentry/node';
22
import type { SentryRollupPluginOptions } from '@sentry/rollup-plugin';
33
import type { SentryVitePluginOptions } from '@sentry/vite-plugin';
4-
import type { createSentryPiniaPlugin, init as initVue } from '@sentry/vue';
4+
import type { init as initVue } from '@sentry/vue';
55

66
// Omitting 'app' as the Nuxt SDK will add the app instance in the client plugin (users do not have to provide this)
7-
export type SentryNuxtClientOptions = Omit<Parameters<typeof initVue>[0] & object, 'app'> & {
8-
/**
9-
* Control if an existing Pinia store should be monitored.
10-
* Set this to `true` to track with default options or provide your custom Pinia plugin options.
11-
*
12-
* This only works if "@pinia/nuxt" is added to the `modules` array.
13-
*
14-
* @default false
15-
*/
16-
trackPinia?: true | Parameters<typeof createSentryPiniaPlugin>[0];
17-
};
18-
7+
export type SentryNuxtClientOptions = Omit<Parameters<typeof initVue>[0] & object, 'app'>;
198
export type SentryNuxtServerOptions = Omit<Parameters<typeof initNode>[0] & object, 'app'>;
209

2110
type SourceMapsOptions = {

packages/nuxt/src/runtime/plugins/sentry.client.ts

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { getClient } from '@sentry/core';
2-
import { consoleSandbox } from '@sentry/utils';
3-
import { browserTracingIntegration, createSentryPiniaPlugin, vueIntegration } from '@sentry/vue';
2+
import { browserTracingIntegration, vueIntegration } from '@sentry/vue';
43
import { defineNuxtPlugin } from 'nuxt/app';
54
import { reportNuxtError } from '../utils';
65

@@ -35,36 +34,18 @@ export default defineNuxtPlugin({
3534
name: 'sentry-client-integrations',
3635
dependsOn: ['sentry-client-config'],
3736
async setup(nuxtApp) {
38-
const sentryClient = getClient();
39-
const clientOptions = sentryClient && sentryClient.getOptions();
40-
4137
// This evaluates to true unless __SENTRY_TRACING__ is text-replaced with "false", in which case everything inside
4238
// will get tree-shaken away
4339
if (typeof __SENTRY_TRACING__ === 'undefined' || __SENTRY_TRACING__) {
40+
const sentryClient = getClient();
41+
4442
if (sentryClient && '$router' in nuxtApp) {
4543
sentryClient.addIntegration(
4644
browserTracingIntegration({ router: nuxtApp.$router as VueRouter, routeLabel: 'path' }),
4745
);
4846
}
4947
}
5048

51-
if (clientOptions && 'trackPinia' in clientOptions && clientOptions.trackPinia) {
52-
if ('$pinia' in nuxtApp) {
53-
(nuxtApp.$pinia as { use: (plugin: unknown) => void }).use(
54-
// `trackPinia` is an object with custom options or `true` (pass `undefined` to use default options)
55-
createSentryPiniaPlugin(clientOptions.trackPinia === true ? undefined : clientOptions.trackPinia),
56-
);
57-
} else {
58-
clientOptions.debug &&
59-
consoleSandbox(() => {
60-
// eslint-disable-next-line no-console
61-
console.warn(
62-
'[Sentry] You set `trackPinia`, but the Pinia module was not found. Make sure to add `"@pinia/nuxt"` to your modules array.',
63-
);
64-
});
65-
}
66-
}
67-
6849
nuxtApp.hook('app:created', vueApp => {
6950
const sentryClient = getClient();
7051

0 commit comments

Comments
 (0)