diff --git a/.size-limit.js b/.size-limit.js
index aee03e5a242c..461de7995ad1 100644
--- a/.size-limit.js
+++ b/.size-limit.js
@@ -78,4 +78,10 @@ module.exports = [
limit: '48 KB',
ignore: ['@sentry/browser', '@sentry/utils', '@sentry/core', '@sentry/types'],
},
+ {
+ name: '@sentry/browser + @sentry/tracing + @sentry/replay - ES6 CDN Bundle (gzipped + minified)',
+ path: 'packages/tracing/build/bundles/bundle.tracing.replay.min.js',
+ gzip: true,
+ limit: '80 KB',
+ },
];
diff --git a/packages/replay/README.md b/packages/replay/README.md
index e3dccaa73ac0..187288a315ff 100644
--- a/packages/replay/README.md
+++ b/packages/replay/README.md
@@ -99,19 +99,11 @@ replay.start();
## Loading Replay as a CDN Bundle
As an alternative to the NPM package, you can load the Replay integration bundle from our CDN.
-Note that the Replay bundle **only contains the Replay integration** and not the entire Sentry SDK.
-You have to add it in addition to the Sentry Browser SDK bundle:
```js
// Browser SDK bundle
-
-// Replay integration bundle
-
@@ -132,6 +124,19 @@ Sentry.init({
The Replay initilialization [configuration](#configuration) options are identical to the options of the NPM package.
+Alternatively, you can also load the Replay integration separately from other bundles:
+
+```html
+
+
+```
+
Please visit our [CDN bundle docs](https://docs.sentry.io/platforms/javascript/install/cdn/#available-bundles) to get the correct `integrity` checksums for your version.
Note that the two bundle versions always have to match.
diff --git a/packages/tracing/rollup.bundle.config.js b/packages/tracing/rollup.bundle.config.js
index 0d5f4fcc8867..a5f7141b9b74 100644
--- a/packages/tracing/rollup.bundle.config.js
+++ b/packages/tracing/rollup.bundle.config.js
@@ -1,5 +1,9 @@
+import replace from '@rollup/plugin-replace';
+
import { makeBaseBundleConfig, makeBundleConfigVariants } from '../../rollup/index.js';
+import pkg from './package.json';
+
const builds = [];
['es5', 'es6'].forEach(jsVersion => {
@@ -14,4 +18,26 @@ const builds = [];
builds.push(...makeBundleConfigVariants(baseBundleConfig));
});
+// Full bundle incl. replay only avaialable for es6
+const replayBaseBundleConfig = makeBaseBundleConfig({
+ bundleType: 'standalone',
+ entrypoints: ['src/index.bundle.replay.ts'],
+ jsVersion: 'es6',
+ licenseTitle: '@sentry/tracing & @sentry/browser & @sentry/replay',
+ outputFileBase: () => 'bundles/bundle.tracing.replay',
+ includeReplay: true,
+ packageSpecificConfig: {
+ plugins: [
+ replace({
+ preventAssignment: true,
+ values: {
+ __SENTRY_REPLAY_VERSION__: JSON.stringify(pkg.version),
+ },
+ }),
+ ],
+ },
+});
+
+builds.push(...makeBundleConfigVariants(replayBaseBundleConfig));
+
export default builds;
diff --git a/packages/tracing/src/index.bundle.replay.ts b/packages/tracing/src/index.bundle.replay.ts
new file mode 100644
index 000000000000..b70b443ef682
--- /dev/null
+++ b/packages/tracing/src/index.bundle.replay.ts
@@ -0,0 +1,7 @@
+import { Replay } from '@sentry/browser';
+
+import * as Sentry from './index.bundle';
+
+Sentry.Integrations.Replay = Replay;
+
+export default Sentry;
diff --git a/packages/tracing/src/index.bundle.ts b/packages/tracing/src/index.bundle.ts
index 13d2bb38c2e2..635be146d639 100644
--- a/packages/tracing/src/index.bundle.ts
+++ b/packages/tracing/src/index.bundle.ts
@@ -53,6 +53,7 @@ export {
export { SDK_VERSION } from '@sentry/browser';
import { Integrations as BrowserIntegrations } from '@sentry/browser';
+import type { Integration } from '@sentry/types';
import { GLOBAL_OBJ } from '@sentry/utils';
import { BrowserTracing } from './browser';
@@ -67,7 +68,11 @@ if (GLOBAL_OBJ.Sentry && GLOBAL_OBJ.Sentry.Integrations) {
windowIntegrations = GLOBAL_OBJ.Sentry.Integrations;
}
-const INTEGRATIONS = {
+// For whatever reason, it does not recognize BrowserTracing or some of the BrowserIntegrations as Integration
+const INTEGRATIONS: Record<
+ string,
+ Integration | typeof BrowserTracing | typeof BrowserIntegrations[keyof typeof BrowserIntegrations]
+> = {
...windowIntegrations,
...BrowserIntegrations,
BrowserTracing,
diff --git a/packages/tracing/test/index.bundle.replay.test.ts b/packages/tracing/test/index.bundle.replay.test.ts
new file mode 100644
index 000000000000..7a55d4c6741e
--- /dev/null
+++ b/packages/tracing/test/index.bundle.replay.test.ts
@@ -0,0 +1,19 @@
+import Sentry from '../src/index.bundle.replay';
+
+// Because of the way how we re-export stuff for the replay bundle, we only have a single default export
+const { Integrations } = Sentry;
+
+describe('Integrations export', () => {
+ it('is exported correctly', () => {
+ Object.keys(Integrations).forEach(key => {
+ // Skip BrowserTracing because it doesn't have a static id field.
+ if (key === 'BrowserTracing') {
+ return;
+ }
+
+ expect((Integrations[key] as any).id).toStrictEqual(expect.any(String));
+ });
+
+ expect(Integrations.Replay).toBeDefined();
+ });
+});
diff --git a/packages/tracing/test/index.bundle.test.ts b/packages/tracing/test/index.bundle.test.ts
index 91f643128d21..494c94a28bfb 100644
--- a/packages/tracing/test/index.bundle.test.ts
+++ b/packages/tracing/test/index.bundle.test.ts
@@ -8,9 +8,9 @@ describe('Integrations export', () => {
return;
}
- expect(Integrations[key as keyof Omit].id).toStrictEqual(
- expect.any(String),
- );
+ expect((Integrations[key] as any).id).toStrictEqual(expect.any(String));
});
});
+
+ expect(Integrations.Replay).toBeUndefined();
});
diff --git a/packages/tracing/tsconfig.types.json b/packages/tracing/tsconfig.types.json
index 1df465fa6534..0abe8142d426 100644
--- a/packages/tracing/tsconfig.types.json
+++ b/packages/tracing/tsconfig.types.json
@@ -5,7 +5,7 @@
// the fact that it introduces a dependency on `@sentry/browser` which doesn't exist anywhere else in the SDK, which
// then prevents us from building that and this at the same time when doing a parallellized build from the repo root
// level.
- "exclude": ["src/index.bundle.ts"],
+ "exclude": ["src/index.bundle.ts", "src/index.bundle.replay.ts"],
"compilerOptions": {
"declaration": true,
diff --git a/rollup/bundleHelpers.js b/rollup/bundleHelpers.js
index e5870d7aaba8..5e1772b99ea1 100644
--- a/rollup/bundleHelpers.js
+++ b/rollup/bundleHelpers.js
@@ -23,7 +23,8 @@ import { mergePlugins } from './utils';
const BUNDLE_VARIANTS = ['.js', '.min.js', '.debug.min.js'];
export function makeBaseBundleConfig(options) {
- const { bundleType, entrypoints, jsVersion, licenseTitle, outputFileBase, packageSpecificConfig } = options;
+ const { bundleType, entrypoints, jsVersion, licenseTitle, outputFileBase, packageSpecificConfig, includeReplay } =
+ options;
const nodeResolvePlugin = makeNodeResolvePlugin();
const sucrasePlugin = makeSucrasePlugin();
@@ -45,9 +46,13 @@ export function makeBaseBundleConfig(options) {
name: 'Sentry',
},
context: 'window',
- plugins: [markAsBrowserBuildPlugin, excludeReplayPlugin],
+ plugins: [markAsBrowserBuildPlugin],
};
+ if (!includeReplay) {
+ standAloneBundleConfig.plugins.push(excludeReplayPlugin);
+ }
+
// used by `@sentry/integrations` and `@sentry/wasm` (bundles which need to be combined with a stand-alone SDK bundle)
const addOnBundleConfig = {
// These output settings are designed to mimic an IIFE. We don't use Rollup's `iife` format because we don't want to