From b31372ead169fb5b889a10ae3eefc18ec6ce6d6e Mon Sep 17 00:00:00 2001 From: Ben Booth Date: Mon, 13 Apr 2026 11:56:03 +1000 Subject: [PATCH 1/2] fix(pixel): support environment in snippet generator for non-prod endpoints The pixel init already accepted an environment param but the snippet generator did not expose it, causing internal pages (e.g. game page) to always hit the production API even when running in dev/sandbox. Co-Authored-By: Claude Opus 4.6 --- packages/audience/pixel/src/pixel.ts | 5 +++++ packages/audience/pixel/src/snippet.test.ts | 24 +++++++++++++++++++++ packages/audience/pixel/src/snippet.ts | 10 ++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/packages/audience/pixel/src/pixel.ts b/packages/audience/pixel/src/pixel.ts index 9d5d8cca5b..20d97a729d 100644 --- a/packages/audience/pixel/src/pixel.ts +++ b/packages/audience/pixel/src/pixel.ts @@ -35,6 +35,11 @@ const PIXEL_VERSION: string = typeof PIXEL_VERSION_INJECTED !== 'undefined' export interface PixelInitOptions { key: string; + /** + * Target environment for the API endpoint. Defaults to `'production'`. + * Only set this for internal Immutable pages that need to target + * non-production backends (e.g. dev, sandbox). + */ environment?: Environment; consent?: ConsentLevel; /** Set to 'auto' to auto-detect consent from CMPs (Google Consent Mode, IAB TCF). */ diff --git a/packages/audience/pixel/src/snippet.test.ts b/packages/audience/pixel/src/snippet.test.ts index efef6c254d..b47be5ce38 100644 --- a/packages/audience/pixel/src/snippet.test.ts +++ b/packages/audience/pixel/src/snippet.test.ts @@ -45,4 +45,28 @@ describe('generateSnippet', () => { expect(html).toContain('s.async=1'); expect(html).toContain('document.head.appendChild(s)'); }); + + it('includes environment in init args when not production', () => { + const html = generateSnippet({ key: 'pk_test_123', environment: 'dev' }); + + expect(html).toContain('"environment":"dev"'); + }); + + it('includes sandbox environment in init args', () => { + const html = generateSnippet({ key: 'pk_test_123', environment: 'sandbox' }); + + expect(html).toContain('"environment":"sandbox"'); + }); + + it('omits environment from init args when set to production', () => { + const html = generateSnippet({ key: 'pk_test_123', environment: 'production' }); + + expect(html).not.toContain('environment'); + }); + + it('omits environment from init args when not provided', () => { + const html = generateSnippet({ key: 'pk_test_123' }); + + expect(html).not.toContain('environment'); + }); }); diff --git a/packages/audience/pixel/src/snippet.ts b/packages/audience/pixel/src/snippet.ts index ef5c7d59bb..8da1242b73 100644 --- a/packages/audience/pixel/src/snippet.ts +++ b/packages/audience/pixel/src/snippet.ts @@ -1,15 +1,23 @@ +import type { Environment } from '@imtbl/audience-core'; + const DEFAULT_CDN_URL = 'https://cdn.immutable.com/pixel/v1/imtbl.js'; export interface SnippetOptions { key: string; cdnUrl?: string; consent?: 'none' | 'anonymous' | 'full'; + environment?: Environment; } export function generateSnippet(options: SnippetOptions): string { - const { key, cdnUrl = DEFAULT_CDN_URL, consent } = options; + const { + key, cdnUrl = DEFAULT_CDN_URL, consent, environment, + } = options; const initArgs: Record = { key }; + if (environment && environment !== 'production') { + initArgs.environment = environment; + } if (consent) { initArgs.consent = consent; } From 76ce8f189858ec439c72c881e066a60f2c7821b6 Mon Sep 17 00:00:00 2001 From: Ben Booth Date: Mon, 13 Apr 2026 12:03:16 +1000 Subject: [PATCH 2/2] fix(pixel): remove environment JSDoc from PixelInitOptions Co-Authored-By: Claude Opus 4.6 --- packages/audience/pixel/src/pixel.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/audience/pixel/src/pixel.ts b/packages/audience/pixel/src/pixel.ts index 20d97a729d..9d5d8cca5b 100644 --- a/packages/audience/pixel/src/pixel.ts +++ b/packages/audience/pixel/src/pixel.ts @@ -35,11 +35,6 @@ const PIXEL_VERSION: string = typeof PIXEL_VERSION_INJECTED !== 'undefined' export interface PixelInitOptions { key: string; - /** - * Target environment for the API endpoint. Defaults to `'production'`. - * Only set this for internal Immutable pages that need to target - * non-production backends (e.g. dev, sandbox). - */ environment?: Environment; consent?: ConsentLevel; /** Set to 'auto' to auto-detect consent from CMPs (Google Consent Mode, IAB TCF). */