Skip to content

Commit

Permalink
feat(nuxt): Expose vueIntegration (#14526)
Browse files Browse the repository at this point in the history
  • Loading branch information
lforst authored Dec 2, 2024
1 parent 44477df commit 9b9ec77
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,11 @@ Sentry.init({
dsn: useRuntimeConfig().public.sentry.dsn,
tunnel: `http://localhost:3031/`, // proxy server
tracesSampleRate: 1.0,
trackComponents: true,
integrations: [
Sentry.vueIntegration({
tracingOptions: {
trackComponents: true,
},
}),
],
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,11 @@ Sentry.init({
dsn: useRuntimeConfig().public.sentry.dsn,
tunnel: `http://localhost:3031/`, // proxy server
tracesSampleRate: 1.0,
trackComponents: true,
integrations: [
Sentry.vueIntegration({
tracingOptions: {
trackComponents: true,
},
}),
],
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ Sentry.init({
dsn: useRuntimeConfig().public.sentry.dsn,
tunnel: `http://localhost:3031/`, // proxy server
tracesSampleRate: 1.0,
trackComponents: true,
integrations: [
Sentry.piniaIntegration(usePinia(), {
actionTransformer: action => `Transformed: ${action}`,
Expand All @@ -15,5 +14,10 @@ Sentry.init({
...state,
}),
}),
Sentry.vueIntegration({
tracingOptions: {
trackComponents: true,
},
}),
],
});
1 change: 1 addition & 0 deletions packages/nuxt/src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from '@sentry/vue';

export { init } from './sdk';
export { piniaIntegration } from './piniaIntegration';
export { vueIntegration } from './vueIntegration';
36 changes: 36 additions & 0 deletions packages/nuxt/src/client/vueIntegration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { GLOBAL_OBJ, defineIntegration } from '@sentry/core';
import type { VueIntegrationOptions } from '@sentry/vue';

type Options = Omit<
VueIntegrationOptions,
| 'app'
| 'Vue'
// TODO(v9): Should be removed from parent type so we can remove it here
| 'hooks'
// TODO(v9): Should be removed from parent type so we can remove it here
| 'timeout'
// TODO(v9): Should be removed from parent type so we can remove it here
| 'trackComponents'
>;

// Since the options object needs to cross the boundary between some builds (i.e. the nuxt module build and our client
// SDK build) we cannot use a getter that is exported from here. Instead we'll pass the options object through a global
// to the module.
export type GlobalObjWithIntegrationOptions = { _sentryNuxtVueIntegrationOptions?: Options };

// The vue integration is actually set up in the Sentry Client Module. There it is set up as soon as the nuxt app object is available.
// However, we need to export the vueIntegration from the Client SDK. This means all this integration does is store away
// its options for the Sentry Client Module to pick them up when initializing the actual vueIntegration.

/**
* Add additional error and span instrumentation specialized for Vue.
*/
export const vueIntegration = defineIntegration((options: Options = {}) => {
return {
// NOTE: This name is different from the original vueIntegration's name.
name: 'NuxtVueIntegration',
setup() {
(GLOBAL_OBJ as GlobalObjWithIntegrationOptions)._sentryNuxtVueIntegrationOptions = options;
},
};
});
12 changes: 10 additions & 2 deletions packages/nuxt/src/runtime/plugins/sentry.client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getClient } from '@sentry/core';
import { GLOBAL_OBJ, getClient } from '@sentry/core';
import { browserTracingIntegration, vueIntegration } from '@sentry/vue';
import { defineNuxtPlugin } from 'nuxt/app';
import type { GlobalObjWithIntegrationOptions } from '../../client/vueIntegration';
import { reportNuxtError } from '../utils';

// --- Types are copied from @sentry/vue (so it does not need to be exported) ---
Expand Down Expand Up @@ -53,7 +54,14 @@ export default defineNuxtPlugin({
// Adding the Vue integration without the Vue error handler
// Nuxt is registering their own error handler, which is unset after hydration: https://github.com/nuxt/nuxt/blob/d3fdbcaac6cf66d21e25d259390d7824696f1a87/packages/nuxt/src/app/entry.ts#L64-L73
// We don't want to wrap the existing error handler, as it leads to a 500 error: https://github.com/getsentry/sentry-javascript/issues/12515
sentryClient.addIntegration(vueIntegration({ app: vueApp, attachErrorHandler: false }));
sentryClient.addIntegration(
vueIntegration({
// We pick up the options from the "fake" vueIntegration exported by the SDK.
...(GLOBAL_OBJ as GlobalObjWithIntegrationOptions)._sentryNuxtVueIntegrationOptions,
app: vueApp,
attachErrorHandler: false,
}),
);
}
});

Expand Down
1 change: 1 addition & 0 deletions packages/vue/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export { browserTracingIntegration } from './browserTracingIntegration';
export { attachErrorHandler } from './errorhandler';
export { createTracingMixins } from './tracing';
export { vueIntegration } from './integration';
export type { VueIntegrationOptions } from './integration';
export { createSentryPiniaPlugin } from './pinia';
2 changes: 2 additions & 0 deletions packages/vue/src/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const DEFAULT_CONFIG: VueOptions = {

const INTEGRATION_NAME = 'Vue';

export type VueIntegrationOptions = Partial<VueOptions>;

export const vueIntegration = defineIntegration((integrationOptions: Partial<VueOptions> = {}) => {
return {
name: INTEGRATION_NAME,
Expand Down

0 comments on commit 9b9ec77

Please sign in to comment.