This guide covers migrating from the v1 Ember addon format to the v2 addon format.
The v2 addon is a modern Ember v2 addon that works with Embroider and Vite. Key differences:
| Feature | v1 Addon | v2 Addon |
|---|---|---|
| Configuration | config/environment.js |
Direct Sentry.init() call |
| Performance instrumentation | Auto-registered initializer | Manual instance-initializer with browserTracingIntegration |
| Build compatibility | Classic builds only | Embroider & Vite compatible |
// config/environment.js
module.exports = function (environment) {
const ENV = {
// ...
'@sentry/ember': {
sentry: {
dsn: 'YOUR_DSN_HERE',
tracesSampleRate: 1.0,
// ...
},
disablePerformance: false,
disableRunloopPerformance: false,
disableInstrumentComponents: false,
disableInitialLoadInstrumentation: false,
},
};
return ENV;
};// app/app.ts (or app/app.js)
import Application from '@ember/application';
import Resolver from 'ember-resolver';
import loadInitializers from 'ember-load-initializers';
import config from 'your-app/config/environment';
import * as Sentry from '@sentry/ember';
// Initialize Sentry BEFORE the Application class
Sentry.init({
dsn: 'YOUR_DSN_HERE',
tracesSampleRate: 1.0,
// All Sentry browser options are supported
});
export default class App extends Application {
modulePrefix = config.modulePrefix;
podModulePrefix = config.podModulePrefix;
Resolver = Resolver;
}
loadInitializers(App, config.modulePrefix);Remove the @sentry/ember section from config/environment.js.
In v1, performance instrumentation was automatic. In v2, create an instance-initializer.
import type ApplicationInstance from '@ember/application/instance';
import { instrumentAppInstancePerformance } from '@sentry/ember';
export function initialize(appInstance: ApplicationInstance): void {
instrumentAppInstancePerformance(appInstance);
}
export default {
initialize,
};import type ApplicationInstance from '@ember/application/instance';
import { instrumentAppInstancePerformance } from '@sentry/ember';
export function initialize(appInstance: ApplicationInstance): void {
instrumentAppInstancePerformance(appInstance, {
// Disable runloop queue tracking
disableRunloopPerformance: false,
// Disable component render tracking
disableInstrumentComponents: false,
// Track component class definitions (advanced)
enableComponentDefinitions: false,
// Minimum duration (ms) for runloop spans
minimumRunloopQueueDuration: 5,
// Minimum duration (ms) for component render spans
minimumComponentRenderDuration: 2,
// Page load and navigation instrumentation
instrumentPageLoad: true,
instrumentNavigation: true,
// Idle timeout (ms)
idleTimeout: 1000,
});
}
export default {
initialize,
};This works the same in v1 and v2:
// app/routes/my-route.ts
import Route from '@ember/routing/route';
import { instrumentRoutePerformance } from '@sentry/ember';
class MyRoute extends Route {
async model() {
return this.store.findAll('post');
}
}
export default instrumentRoutePerformance(MyRoute);Most imports remain the same, but check for these changes:
// v2 - new import for browserTracingIntegration
import { addIntegration, browserTracingIntegration, instrumentAppInstancePerformance } from '@sentry/ember';
// v2 - same for instrumentRoutePerformance
import { instrumentRoutePerformance } from '@sentry/ember';All exports from @sentry/browser are re-exported from @sentry/ember:
import {
// Core
init,
captureException,
captureMessage,
setUser,
setTag,
setExtra,
addBreadcrumb,
withScope,
// Spans
startSpan,
startInactiveSpan,
getActiveSpan,
// Ember-specific
browserTracingIntegration,
instrumentRoutePerformance,
} from '@sentry/ember';app/
├── app.js
├── index.html (unmodified)
├── routes/
│ └── posts.js
config/
└── environment.js (with @sentry/ember config)
app/app.js:
import Application from '@ember/application';
// Sentry was auto-initialized from configconfig/environment.js:
module.exports = function (environment) {
return {
'@sentry/ember': {
sentry: {
dsn: 'YOUR_DSN',
tracesSampleRate: 1.0,
},
},
};
};app/
├── app.ts
├── instance-initializers/
│ └── sentry-performance.ts
├── routes/
│ └── posts.ts
config/
└── environment.js (no @sentry/ember config)
app/app.ts:
import Application from '@ember/application';
import Resolver from 'ember-resolver';
import loadInitializers from 'ember-load-initializers';
import config from 'my-app/config/environment';
import * as Sentry from '@sentry/ember';
Sentry.init({
dsn: 'YOUR_DSN',
tracesSampleRate: 1.0,
});
export default class App extends Application {
modulePrefix = config.modulePrefix;
podModulePrefix = config.podModulePrefix;
Resolver = Resolver;
}
loadInitializers(App, config.modulePrefix);app/instance-initializers/sentry-performance.ts:
import type ApplicationInstance from '@ember/application/instance';
import { instrumentAppInstancePerformance } from '@sentry/ember';
export function initialize(appInstance: ApplicationInstance): void {
instrumentAppInstancePerformance(appInstance);
}
export default { initialize };All exports — including the Ember-specific init, browserTracingIntegration, instrumentAppInstancePerformance and instrumentRoutePerformance — come from the top-level @sentry/ember entry point. There are no subpath imports:
import { browserTracingIntegration, instrumentAppInstancePerformance } from '@sentry/ember';- Ensure
Sentry.init()is called before app boots - Verify the instance-initializer is created at
app/instance-initializers/sentry-performance.ts - Check that
tracesSampleRateis set (e.g.,1.0for 100%)
The performance instrumentation automatically detects FastBoot and disables client-side instrumentation during server rendering. No changes needed.
The following v1-specific features are no longer available:
contentForhooks - The addon no longer injects scripts automatically@embroider/macrosconfig - Use directinit()options- Initial load scripts - No longer needed; page load instrumentation is handled by
browserTracingIntegration