diff --git a/.changeset/fluffy-games-jog.md b/.changeset/fluffy-games-jog.md new file mode 100644 index 000000000..fd2492552 --- /dev/null +++ b/.changeset/fluffy-games-jog.md @@ -0,0 +1,5 @@ +--- +'@guardian/commercial': minor +--- + +Use region specific bundles for Prebid diff --git a/package.json b/package.json index da70b2a78..27de7c52e 100644 --- a/package.json +++ b/package.json @@ -103,10 +103,10 @@ "webpack-merge": "^6.0.1" }, "dependencies": { - "@guardian/prebid.js": "8.52.0-8", "@octokit/core": "^6.1.2", "fastdom": "^1.0.11", "lodash-es": "^4.17.21", + "prebid.js": "guardian/prebid.js#4d50ccf7d3f74561ef9d11a091fde5dd434d9810", "process": "^0.11.10", "tslib": "^2.6.2", "web-vitals": "^4.2.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index efd40d0bf..6da7dc0c1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,9 +5,6 @@ settings: excludeLinksFromLockfile: false dependencies: - '@guardian/prebid.js': - specifier: 8.52.0-8 - version: 8.52.0-8(babel-core@7.0.0-bridge.0)(tslib@2.7.0)(typescript@5.6.3) '@octokit/core': specifier: ^6.1.2 version: 6.1.2 @@ -17,6 +14,9 @@ dependencies: lodash-es: specifier: ^4.17.21 version: 4.17.21 + prebid.js: + specifier: guardian/prebid.js#4d50ccf7d3f74561ef9d11a091fde5dd434d9810 + version: github.com/guardian/prebid.js/4d50ccf7d3f74561ef9d11a091fde5dd434d9810(babel-core@7.0.0-bridge.0)(tslib@2.7.0)(typescript@5.6.3) process: specifier: ^0.11.10 version: 0.11.10 @@ -1998,87 +1998,6 @@ packages: typescript: 5.6.3 dev: true - /@guardian/prebid.js@8.52.0-8(babel-core@7.0.0-bridge.0)(tslib@2.7.0)(typescript@5.6.3): - resolution: {integrity: sha512-JQ9unudgn5DAwLoqEiBdjuEaEFOhR9JZhjHD46pm4306C1XfYF0ts3YWIT9poq6vN1tbMQJw0NQeyXcL5QGIcA==} - engines: {node: '>=12.0.0'} - dependencies: - '@babel/core': 7.26.0 - '@babel/plugin-transform-runtime': 7.25.9(@babel/core@7.26.0) - '@babel/preset-env': 7.26.0(@babel/core@7.26.0) - '@babel/register': 7.25.9(@babel/core@7.26.0) - '@babel/runtime': 7.26.0 - '@guardian/libs': 18.0.2(tslib@2.7.0)(typescript@5.6.3) - core-js: 3.36.1 - core-js-pure: 3.36.1 - criteo-direct-rsa-validate: 1.1.0 - crypto-js: 4.2.0 - dlv: 1.1.3 - dset: 3.1.4 - express: 4.20.0 - fun-hooks: 0.9.10 - gulp-wrap: 0.15.0(babel-core@7.0.0-bridge.0) - klona: 2.0.6 - live-connect-js: 6.7.3 - optionalDependencies: - fsevents: 2.3.3 - transitivePeerDependencies: - - arc-templates - - atpl - - babel-core - - bracket-template - - coffee-script - - dot - - dust - - dustjs-helpers - - dustjs-linkedin - - eco - - ect - - ejs - - haml-coffee - - hamlet - - hamljs - - handlebars - - hogan.js - - htmling - - jade - - jazz - - jqtpl - - just - - liquid-node - - liquor - - marko - - mote - - mustache - - nunjucks - - plates - - pug - - qejs - - ractive - - razor-tmpl - - react - - react-dom - - slm - - squirrelly - - supports-color - - swig - - swig-templates - - teacup - - templayed - - then-jade - - then-pug - - tinyliquid - - toffee - - tslib - - twig - - twing - - typescript - - underscore - - vash - - velocityjs - - walrus - - whiskers - dev: false - /@guardian/prettier@8.0.1(prettier@3.3.3)(tslib@2.7.0): resolution: {integrity: sha512-mELIji0FezEj5YTyHkylB6VNeCN1+/jsHW/iZ0RItDMn/GjU6gbaPP5D2m+BZwrTYNrxYhCoFqCE/ObkEghtdg==} peerDependencies: @@ -9567,3 +9486,87 @@ packages: resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} engines: {node: '>=12.20'} dev: true + + github.com/guardian/prebid.js/4d50ccf7d3f74561ef9d11a091fde5dd434d9810(babel-core@7.0.0-bridge.0)(tslib@2.7.0)(typescript@5.6.3): + resolution: {tarball: https://codeload.github.com/guardian/prebid.js/tar.gz/4d50ccf7d3f74561ef9d11a091fde5dd434d9810} + id: github.com/guardian/prebid.js/4d50ccf7d3f74561ef9d11a091fde5dd434d9810 + name: '@guardian/prebid.js' + version: 8.52.0-8 + engines: {node: '>=12.0.0'} + dependencies: + '@babel/core': 7.26.0 + '@babel/plugin-transform-runtime': 7.25.9(@babel/core@7.26.0) + '@babel/preset-env': 7.26.0(@babel/core@7.26.0) + '@babel/register': 7.25.9(@babel/core@7.26.0) + '@babel/runtime': 7.26.0 + '@guardian/libs': 18.0.2(tslib@2.7.0)(typescript@5.6.3) + core-js: 3.36.1 + core-js-pure: 3.36.1 + criteo-direct-rsa-validate: 1.1.0 + crypto-js: 4.2.0 + dlv: 1.1.3 + dset: 3.1.4 + express: 4.20.0 + fun-hooks: 0.9.10 + gulp-wrap: 0.15.0(babel-core@7.0.0-bridge.0) + klona: 2.0.6 + live-connect-js: 6.7.3 + optionalDependencies: + fsevents: 2.3.3 + transitivePeerDependencies: + - arc-templates + - atpl + - babel-core + - bracket-template + - coffee-script + - dot + - dust + - dustjs-helpers + - dustjs-linkedin + - eco + - ect + - ejs + - haml-coffee + - hamlet + - hamljs + - handlebars + - hogan.js + - htmling + - jade + - jazz + - jqtpl + - just + - liquid-node + - liquor + - marko + - mote + - mustache + - nunjucks + - plates + - pug + - qejs + - ractive + - razor-tmpl + - react + - react-dom + - slm + - squirrelly + - supports-color + - swig + - swig-templates + - teacup + - templayed + - then-jade + - then-pug + - tinyliquid + - toffee + - tslib + - twig + - twing + - typescript + - underscore + - vash + - velocityjs + - walrus + - whiskers + dev: false diff --git a/src/init/consented/prepare-prebid.spec.ts b/src/init/consented/prepare-prebid.spec.ts index 8c5d07733..dfecd281d 100644 --- a/src/init/consented/prepare-prebid.spec.ts +++ b/src/init/consented/prepare-prebid.spec.ts @@ -6,13 +6,14 @@ import type { import { getConsentFor, log, onConsent } from '@guardian/libs'; import { commercialFeatures } from '../../lib/commercial-features'; import { prebid } from '../../lib/header-bidding/prebid/prebid'; -import { isInCanada } from '../../utils/geo-utils'; +import { isInCanada, isInUk } from '../../utils/geo-utils'; import { _ } from './prepare-prebid'; const { setupPrebid } = _; jest.mock('utils/geo-utils', () => ({ isInCanada: jest.fn(() => false), + isInUk: jest.fn(), })); jest.mock('experiments/ab', () => ({ @@ -158,6 +159,7 @@ describe('init', () => { commercialFeatures.adFree = false; mockOnConsent(tcfv2WithConsent); mockGetConsentFor(true); + (isInUk as jest.Mock).mockReturnValueOnce(true); await setupPrebid(); expect(prebid.initialise).toBeCalled(); @@ -173,6 +175,7 @@ describe('init', () => { fakeUserAgent('Google Web Preview'); mockOnConsent(tcfv2WithConsent); mockGetConsentFor(true); + (isInUk as jest.Mock).mockReturnValueOnce(true); await setupPrebid(); expect(prebid.initialise).not.toBeCalled(); @@ -188,6 +191,7 @@ describe('init', () => { }; mockOnConsent(tcfv2WithConsent); mockGetConsentFor(true); + (isInUk as jest.Mock).mockReturnValueOnce(true); await setupPrebid(); expect(prebid.initialise).not.toBeCalled(); @@ -203,7 +207,7 @@ describe('init', () => { commercialFeatures.adFree = false; mockOnConsent(tcfv2WithConsent); mockGetConsentFor(true); - (isInCanada as jest.Mock).mockReturnValueOnce(false); + (isInUk as jest.Mock).mockReturnValueOnce(true); await setupPrebid(); expect(prebid.initialise).toBeCalled(); @@ -235,6 +239,7 @@ describe('init', () => { commercialFeatures.adFree = false; mockOnConsent(tcfv2WithConsent); mockGetConsentFor(true); + (isInUk as jest.Mock).mockReturnValueOnce(true); await setupPrebid(); expect(prebid.initialise).not.toBeCalled(); @@ -250,6 +255,7 @@ describe('init', () => { commercialFeatures.adFree = true; mockOnConsent(tcfv2WithConsent); mockGetConsentFor(true); + (isInUk as jest.Mock).mockReturnValueOnce(true); await setupPrebid(); expect(prebid.initialise).not.toBeCalled(); @@ -266,6 +272,7 @@ describe('init', () => { window.guardian.config.page.hasPageSkin = true; mockOnConsent(tcfv2WithConsent); mockGetConsentFor(true); + (isInUk as jest.Mock).mockReturnValueOnce(true); await setupPrebid(); expect(prebid.initialise).not.toBeCalled(); @@ -280,6 +287,7 @@ describe('init', () => { window.guardian.config.page.hasPageSkin = false; mockOnConsent(tcfv2WithConsent); mockGetConsentFor(true); + (isInUk as jest.Mock).mockReturnValueOnce(true); await setupPrebid(); expect(prebid.initialise).toBeCalled(); @@ -295,6 +303,8 @@ describe('init', () => { commercialFeatures.adFree = false; mockOnConsent(tcfv2WithConsent); mockGetConsentFor(true); + (isInUk as jest.Mock).mockReturnValueOnce(true); + await setupPrebid(); expect(prebid.initialise).toBeCalled(); }); @@ -309,6 +319,7 @@ describe('init', () => { commercialFeatures.adFree = false; mockOnConsent(tcfv2WithoutConsent); mockGetConsentFor(false); + (isInUk as jest.Mock).mockReturnValueOnce(true); await setupPrebid(); expect(log).toHaveBeenCalledWith( @@ -330,6 +341,8 @@ describe('init', () => { commercialFeatures.adFree = false; mockOnConsent(usnatWithConsent); mockGetConsentFor(true); + (isInUk as jest.Mock).mockReturnValueOnce(true); + await setupPrebid(); expect(prebid.initialise).toBeCalled(); }); @@ -344,6 +357,7 @@ describe('init', () => { commercialFeatures.adFree = false; mockOnConsent(usnatWithoutConsent); mockGetConsentFor(false); + (isInUk as jest.Mock).mockReturnValueOnce(true); await setupPrebid(); expect(log).toHaveBeenCalledWith( @@ -365,6 +379,8 @@ describe('init', () => { commercialFeatures.adFree = false; mockOnConsent(ausWithConsent); mockGetConsentFor(true); + (isInUk as jest.Mock).mockReturnValueOnce(true); + await setupPrebid(); expect(prebid.initialise).toBeCalled(); }); @@ -379,6 +395,7 @@ describe('init', () => { commercialFeatures.adFree = false; mockOnConsent(ausWithoutConsent); mockGetConsentFor(false); + (isInUk as jest.Mock).mockReturnValueOnce(true); await setupPrebid(); expect(log).toHaveBeenCalledWith( @@ -400,6 +417,7 @@ describe('init', () => { commercialFeatures.adFree = false; mockOnConsent(invalidWithoutConsent); mockGetConsentFor(true); + (isInUk as jest.Mock).mockReturnValueOnce(true); await setupPrebid(); expect(log).toHaveBeenCalledWith( @@ -421,6 +439,7 @@ describe('init', () => { commercialFeatures.adFree = false; mockOnConsent(tcfv2WithConsent); mockGetConsentForWithCustom(true, false); + (isInUk as jest.Mock).mockReturnValueOnce(true); await setupPrebid(); expect(prebid.initialise).toBeCalled(); @@ -436,6 +455,7 @@ describe('init', () => { commercialFeatures.adFree = false; mockOnConsent(tcfv2WithConsent); mockGetConsentForWithCustom(false, true); + (isInUk as jest.Mock).mockReturnValueOnce(true); await setupPrebid(); expect(prebid.initialise).toBeCalled(); @@ -451,6 +471,7 @@ describe('init', () => { commercialFeatures.adFree = false; mockOnConsent(tcfv2WithConsent); mockGetConsentForWithCustom(false, false); + (isInUk as jest.Mock).mockReturnValueOnce(true); await setupPrebid(); expect(log).toHaveBeenCalledWith( diff --git a/src/init/consented/prepare-prebid.ts b/src/init/consented/prepare-prebid.ts index 950f08fdd..bc22f39aa 100644 --- a/src/init/consented/prepare-prebid.ts +++ b/src/init/consented/prepare-prebid.ts @@ -5,7 +5,7 @@ import { commercialFeatures } from '../../lib/commercial-features'; import { isGoogleProxy } from '../../lib/detect/detect-google-proxy'; import { prebid } from '../../lib/header-bidding/prebid/prebid'; import { shouldIncludeOnlyA9 } from '../../lib/header-bidding/utils'; -import { isInCanada } from '../../utils/geo-utils'; +import { isInAuOrNz, isInCanada, isInUk, isInUsa } from '../../utils/geo-utils'; const shouldLoadPrebid = () => !isGoogleProxy() && @@ -16,11 +16,22 @@ const shouldLoadPrebid = () => !shouldIncludeOnlyA9 && !isInCanada(); +const prebidVersion = () => { + if (isInUk()) { + return 'uk'; + } else if (isInAuOrNz()) { + return 'aus-nz'; + } else if (isInUsa()) { + return 'us'; + } + return 'row'; +}; + const loadPrebid = async (framework: ConsentFramework): Promise => { if (shouldLoadPrebid()) { await import( - // @ts-expect-error -- there’s no types for Prebid.js - /* webpackChunkName: "Prebid.js" */ '@guardian/prebid.js/build/dist/prebid' + /* webpackChunkName: "Prebid.js" */ + `prebid.js/build/dist/${prebidVersion()}/prebid` ); prebid.initialise(window, framework); } diff --git a/src/lib/header-bidding/prebid/prebid.spec.ts b/src/lib/header-bidding/prebid/prebid.spec.ts index 3fecba15b..1abc32109 100644 --- a/src/lib/header-bidding/prebid/prebid.spec.ts +++ b/src/lib/header-bidding/prebid/prebid.spec.ts @@ -1,7 +1,9 @@ +import { isInUk as isInUk_ } from '../../../utils/geo-utils'; import { getAdvertById as getAdvertById_ } from '../../dfp/get-advert-by-id'; import { prebid } from './prebid'; const getAdvertById = getAdvertById_ as jest.Mock; +const isInUk = isInUk_ as jest.Mock; jest.mock('define/Advert', () => jest.fn().mockImplementation(() => ({ advert: jest.fn() })), @@ -19,12 +21,15 @@ jest.mock('experiments/ab', () => ({ isUserInVariant: jest.fn(), })); +jest.mock('utils/geo-utils'); + const resetPrebid = () => { delete window.pbjs; // @ts-expect-error -- there’s no types for this delete window.pbjsChunk; + isInUk.mockReturnValue(true); jest.resetModules(); - jest.requireActual('@guardian/prebid.js/build/dist/prebid'); + jest.requireActual('prebid.js/build/dist/uk/prebid'); }; describe('initialise', () => {