diff --git a/.changeset/kind-crabs-report.md b/.changeset/kind-crabs-report.md new file mode 100644 index 000000000..4d1e24530 --- /dev/null +++ b/.changeset/kind-crabs-report.md @@ -0,0 +1,5 @@ +--- +'@segment/analytics-next': minor +--- + +Support loading analytics into a custom global variable when using snippet version 5.2.1 or later diff --git a/packages/browser-integration-tests/src/custom-global-key.test.ts b/packages/browser-integration-tests/src/custom-global-key.test.ts new file mode 100644 index 000000000..5e1ed6187 --- /dev/null +++ b/packages/browser-integration-tests/src/custom-global-key.test.ts @@ -0,0 +1,54 @@ +import { test, expect } from '@playwright/test' +import { standaloneMock } from './helpers/standalone-mock' +import { extractWriteKeyFromUrl } from './helpers/extract-writekey' +import { CDNSettingsBuilder } from '@internal/test-helpers' + +test.describe('Segment with custom global key', () => { + test.beforeEach(standaloneMock) + test.beforeEach(async ({ context }) => { + await context.route( + 'https://cdn.segment.com/v1/projects/*/settings', + (route, request) => { + if (request.method().toLowerCase() !== 'get') { + return route.continue() + } + + const writeKey = extractWriteKeyFromUrl(request.url()) || 'writeKey' + return route.fulfill({ + status: 200, + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(new CDNSettingsBuilder({ writeKey }).build()), + }) + } + ) + }) + + test('supports using a custom global key', async ({ page }) => { + // Load analytics.js + await page.goto('/standalone-custom-key.html') + await page.evaluate(() => { + ;(window as any).segment_analytics.track('track before load') + ;(window as any).segment_analytics.load('fake-key') + }) + + const req = await page.waitForRequest('https://api.segment.io/v1/t') + + // confirm that any events triggered before load have been sent + expect(req.postDataJSON().event).toBe('track before load') + + const contextObj = await page.evaluate(() => + (window as any).segment_analytics.track('track after load') + ) + + // confirm that any events triggered after load return a regular context object + expect(contextObj).toMatchObject( + expect.objectContaining({ + attempts: expect.anything(), + event: expect.objectContaining({ event: 'track after load' }), + stats: expect.objectContaining({ metrics: expect.anything() }), + }) + ) + }) +}) diff --git a/packages/browser-integration-tests/standalone-custom-key.html b/packages/browser-integration-tests/standalone-custom-key.html new file mode 100644 index 000000000..f8d01f773 --- /dev/null +++ b/packages/browser-integration-tests/standalone-custom-key.html @@ -0,0 +1,94 @@ + + + + + + + diff --git a/packages/browser/src/browser/standalone.ts b/packages/browser/src/browser/standalone.ts index 69f86f6fe..039653eee 100644 --- a/packages/browser/src/browser/standalone.ts +++ b/packages/browser/src/browser/standalone.ts @@ -28,6 +28,7 @@ import { loadAjsClassicFallback, isAnalyticsCSPError, } from '../lib/csp-detection' +import { setGlobalAnalyticsKey } from '../lib/global-analytics-helper' let ajsIdentifiedCSP = false @@ -71,6 +72,16 @@ async function attempt(promise: () => Promise) { } } +const globalAnalyticsKey = ( + document.querySelector( + 'script[data-global-segment-analytics-key]' + ) as HTMLScriptElement +)?.dataset.globalSegmentAnalyticsKey + +if (globalAnalyticsKey) { + setGlobalAnalyticsKey(globalAnalyticsKey) +} + if (shouldPolyfill()) { // load polyfills in order to get AJS to work with old browsers const script = document.createElement('script')