From 939715c84ed73c9ad1517c6faadf6a9f98599088 Mon Sep 17 00:00:00 2001 From: Harsh Joshi Date: Tue, 16 Jun 2026 11:23:45 +0530 Subject: [PATCH 1/3] fix(hubspot-web): add id=hs-script-loader to prevent duplicate script injection Co-Authored-By: Claude Opus 4.8 (1M context) --- .../hubspot-web/src/__tests__/index.test.ts | 13 +++++++++++++ .../destinations/hubspot-web/src/index.ts | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/browser-destinations/destinations/hubspot-web/src/__tests__/index.test.ts b/packages/browser-destinations/destinations/hubspot-web/src/__tests__/index.test.ts index fdcb5c06e07..37c0dca7c69 100644 --- a/packages/browser-destinations/destinations/hubspot-web/src/__tests__/index.test.ts +++ b/packages/browser-destinations/destinations/hubspot-web/src/__tests__/index.test.ts @@ -37,6 +37,19 @@ describe('Hubspot Web (Actions)', () => { expect(window.hbspt).toBeUndefined() }) + test('loads hubspot script with id=hs-script-loader to prevent duplicate script injection', async () => { + const [event] = await hubspotDestination({ + portalId: '12345', + subscriptions + }) + + await event.load(Context.system(), {} as Analytics) + + const scripts = Array.from(document.querySelectorAll('script')) + const hubspotScript = scripts.find((s) => s.src.includes('hs-scripts.com')) + expect(hubspotScript?.id).toBe('hs-script-loader') + }) + test('loads hubspot analytics with EU script', async () => { const [event] = await hubspotDestination({ portalId: '12345', diff --git a/packages/browser-destinations/destinations/hubspot-web/src/index.ts b/packages/browser-destinations/destinations/hubspot-web/src/index.ts index d327613318e..def10b6440c 100644 --- a/packages/browser-destinations/destinations/hubspot-web/src/index.ts +++ b/packages/browser-destinations/destinations/hubspot-web/src/index.ts @@ -92,7 +92,7 @@ export const destination: BrowserDestinationDefinition = { ? 'https://js-eu1.hsforms.net/forms/v2.js' : 'https://js.hsforms.net/forms/v2.js' - await deps.loadScript(scriptPath) + await deps.loadScript(scriptPath, { id: 'hs-script-loader' }) if (settings.loadFormsSDK) { await deps.loadScript(formsScriptPath) } From 46acb48241fe5620c7c5b8cb8956851a4297a9e1 Mon Sep 17 00:00:00 2001 From: Harsh Joshi Date: Tue, 16 Jun 2026 13:22:36 +0530 Subject: [PATCH 2/3] test(hubspot-web): assert exactly one hs-script-loader script with correct src Addresses Copilot review: tighten the regression guard to select by script#hs-script-loader, assert exactly one element exists, and verify its src is the HubSpot loader URL. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../destinations/hubspot-web/src/__tests__/index.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/browser-destinations/destinations/hubspot-web/src/__tests__/index.test.ts b/packages/browser-destinations/destinations/hubspot-web/src/__tests__/index.test.ts index 37c0dca7c69..cbbf2dc8acb 100644 --- a/packages/browser-destinations/destinations/hubspot-web/src/__tests__/index.test.ts +++ b/packages/browser-destinations/destinations/hubspot-web/src/__tests__/index.test.ts @@ -45,9 +45,9 @@ describe('Hubspot Web (Actions)', () => { await event.load(Context.system(), {} as Analytics) - const scripts = Array.from(document.querySelectorAll('script')) - const hubspotScript = scripts.find((s) => s.src.includes('hs-scripts.com')) - expect(hubspotScript?.id).toBe('hs-script-loader') + const loaderScripts = Array.from(document.querySelectorAll('script#hs-script-loader')) + expect(loaderScripts).toHaveLength(1) + expect(loaderScripts[0].src).toBe('https://js.hs-scripts.com/12345.js') }) test('loads hubspot analytics with EU script', async () => { From efc5c4fb037bd74f797a2d578bd72e5e7a459724 Mon Sep 17 00:00:00 2001 From: Harsh Joshi Date: Wed, 17 Jun 2026 11:57:30 +0530 Subject: [PATCH 3/3] test(hubspot-web): assert literal injected src via getAttribute Addresses deepreview: getAttribute('src') checks the literal injected value rather than the IDL-resolved absolute URL, so the assertion stays meaningful even if the injected URL ever became relative. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../destinations/hubspot-web/src/__tests__/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/browser-destinations/destinations/hubspot-web/src/__tests__/index.test.ts b/packages/browser-destinations/destinations/hubspot-web/src/__tests__/index.test.ts index cbbf2dc8acb..f5985aa8985 100644 --- a/packages/browser-destinations/destinations/hubspot-web/src/__tests__/index.test.ts +++ b/packages/browser-destinations/destinations/hubspot-web/src/__tests__/index.test.ts @@ -47,7 +47,7 @@ describe('Hubspot Web (Actions)', () => { const loaderScripts = Array.from(document.querySelectorAll('script#hs-script-loader')) expect(loaderScripts).toHaveLength(1) - expect(loaderScripts[0].src).toBe('https://js.hs-scripts.com/12345.js') + expect(loaderScripts[0].getAttribute('src')).toBe('https://js.hs-scripts.com/12345.js') }) test('loads hubspot analytics with EU script', async () => {