Prebid.js 10 → 11 migration.
Every verified breaking change in Prebid.js 11.0 (March 2026), ordered into a pre-flight → migrate → validate checklist.
Prebid.js 11.0, released March 12, 2026, is a breaking major release of the open-source header-bidding wrapper. Upgrading from 10.x means absorbing removed modules — including all Adpod and PAAPI support — three deleted events, consolidated GPT slot matching, and strict media-type validation. This page is the ordered migration checklist the official changelogs don’t provide.
The official 11.0 notes are a changelog. A changelog tells you what changed; it does not tell you the order, the risk ranking, or what to monitor. That gap is this page.
- Prebid.js 11.0 released Mar 12, 2026
- 11.x line 11.23.0 · Jul 8, 2026
- Prebid.js 10.x past the 30-day support minimum
Fast read
- What it is
- An operator checklist for upgrading Prebid.js from the 10.x line to 11.x: every verified breaking change in 11.0, ordered into pre-flight, migrate, and validate phases. The official release notes are changelogs; this is the migration playbook they do not provide.
- What breaks
- The Adpod and PAAPI module suites are removed outright; three events die (addAdUnits, bidAccepted, seatNonBid); GPT slot matching consolidates into one option; mediaType validation turns strict by default; storageControl enforcement turns strict; DNT support is gone; six-plus adapters leave the tree.
- The go/no-go
- Adpod (long-form / CTV pods) and PAAPI (Protected Audience) have no replacement in Prebid.js 11. A build that depends on either faces an architecture decision, not a code fix — make it before touching config.
- Support reality
- There is no LTS program. Prebid.org commits to supporting the previous major for a minimum of 30 days after a new major ships — the only documented commitment. 11.0 shipped March 12, 2026, so 10.x has been effectively unsupported since roughly April 2026.
- Best for
- Publisher ad-ops and dev teams running Prebid.js 10.x, wrapper managed-service operators, analytics vendors with Prebid adapters, and anyone debugging a revenue drop that started with an upgrade.
- Watch-out
- The highest-risk failures are silent: removed events stop analytics without an error, and strict mediaType validation rejects bids quietly. Monitor event and bid-rate parity against the 10.x baseline — do not wait for the revenue report.
Every verified breaking change in 11.0.
Nine changes, each verified against the official release notes. Two are go/no-go decisions, three fail loudly, and four fail silently — the silent ones are where revenue leaks.
| Change | Who’s affected | What to do | Source |
|---|---|---|---|
| Adpod suite removed — adpod, categoryTranslation, dfpAdpod, gamAdpod, freeWheelAdserverVideo, dfpAdServerVideo | CTV and long-form video publishers building ad pods through Prebid.js | No replacement exists. Treat as a go/no-go architecture decision: stay on an unsupported 10.x, or move pod assembly outside Prebid.js. | 11.0.0 release notes |
| PAAPI suite removed — paapi, paapiForGpt, topLevelPaapi | Anyone testing Protected Audience through Prebid.js modules | No replacement exists. Remove the modules from the build; PAAPI experimentation moves outside the wrapper. | 11.0.0 release notes |
| Three events removed — addAdUnits, bidAccepted, seatNonBid | Analytics adapters and custom event listeners — the failure is silent: listeners simply stop firing | Remap: addAdUnits → auctionInit or beforeRequestBids; bidAccepted → bidResponse; seatNonBid → pbsAnalytics. Audit every analytics adapter in the build. | pb11 release notes |
| GPT slot matching consolidated — setTargetingForGPTAsync loses its customSlotMatching argument; gptPreAuction.customGptSlotMatching and bidViewability.customMatchFunction removed | Wrappers passing a second argument to setTargetingForGPTAsync, and users of either removed module option | Move all three to the single new top-level customGptSlotMatching setConfig option. | pb11 release notes |
| Strict mediaType validation by default — bids whose mediaType does not match the ad unit’s declared mediaTypes are rejected | Every publisher; bidders returning loosely-typed responses lose bids quietly | Monitor bid-rejection logs after upgrading. Opt out with auctionOptions.rejectInvalidMediaTypes: false only as a diagnostic. A second flag, rejectUnknownMediaTypes (off by default), rejects bids that declare no mediaType at all. | pb11 release notes |
| storageControl enforcement turns strict — undisclosed storage access fails instead of logging a warning | Only builds that include the storageControl module | Run 11.x in staging with strict enforcement, catalog the failures, fix module disclosures. Revert with storageControl: { enforcement: 'off' } if needed. | pb11 release notes |
| Viewability overhaul — new adUnit.element property links ad units to DOM elements; adapters use getAdUnitElement() | Publishers whose container div id differs from the ad unit code (the default fallback is document.getElementById(adUnit.code)) | Set adUnit.element explicitly where ids diverge. Post-render measurement runs through bidViewability (GPT-only) or bidViewabilityIO (IntersectionObserver); both fire bidViewable, onBidViewable, and "viewable-mrc50" trackers. | pb11 release notes |
| DNT support removed — getDNT() always returns false; navigator.doNotTrack is ignored | Anyone with DNT-conditional logic in page or adapter code | Delete the logic. Privacy gating belongs in consent modules and Activity Controls, not DNT. | pb11 release notes |
| Adapters and modules removed — quantcastBidAdapter, quantcastIdSystem, dmdIdSystem, optableBidAdapter, ringieraxelspringerBidAdapter, express, intersectionRtdProvider | Builds referencing any of these — the build itself fails | Remove them from the build config; source the demand or identity relationship elsewhere. | 11.0.0 release notes |
The strategic casualty: Adpod
The Adpod removal is the one change on this list with no engineering answer. CTV and long-form video publishers assembling ad pods through Prebid.js lose the capability entirely — Prebid.js 11 offers no replacement path. The honest options are staying on an unsupported 10.x (see the support reality below) or moving pod assembly to the ad server or a server-side stack. Decide this before scheduling the migration; it can invalidate the whole plan.
The migration checklist: ten steps, three phases.
Ordered by dependency, not by changelog position. Pre-flight finds the work, migrate does it, validate proves it — and the go/no-go on Adpod and PAAPI precedes step one.
Phase 1 — Pre-flight: audit before touching code.
- Inventory the build against the removed-module list. Run pbjs.installedModules and compare against every module removed in 11.0 (table above). Flag Adpod and PAAPI dependencies separately — those are go/no-go decisions, not code fixes.
- Confirm the 10.0 prerequisites are already absorbed. bid.userId stopped being populated in 10.0 — identity must read from userIdAsEids or ortb2.user.ext.eids. Schain moved to ortb2.source.ext.schain; gpid replaced pbadslot. Anyone jumping 9 → 11 must complete the pb10-notes list first. If you are cleanly on 10.x, this is a confirmation, not work.
- Grep integration code for the removed surfaces. Search page code, wrapper code, and analytics adapters for addAdUnits, bidAccepted, and seatNonBid event listeners, and for any second argument passed to setTargetingForGPTAsync. Every hit is a migration task.
Phase 2 — Migrate: the five code changes.
- Unify slot matching on customGptSlotMatching. Replace the setTargetingForGPTAsync second argument, gptPreAuction.customGptSlotMatching, and bidViewability.customMatchFunction with the single top-level customGptSlotMatching setConfig option.
- Add adUnit.element where the div id diverges from the ad unit code. The default element lookup is document.getElementById(adUnit.code). Where that fails, viewability and rendering linkage silently degrade — set element explicitly.
- Set the mediaType validation posture deliberately. Keep the strict default and monitor bid-rejection logs first. Only consider auctionOptions.rejectInvalidMediaTypes: false if rejections are demonstrably wrong. Separately evaluate enabling rejectUnknownMediaTypes — undeclared mediaTypes otherwise silently default to banner.
- Stage storageControl strict enforcement. If the module is in the build: run 11.x in staging, catalog storage-access failures, fix disclosures before production. storageControl: { enforcement: 'off' } is the escape hatch, not the plan.
- Delete DNT-conditional logic. getDNT() always returns false in 11.x. Any behavior branching on it is dead code at best, a compliance illusion at worst.
Phase 3 — Validate: prove parity, then roll.
- Audit initialization ordering. A May 2026 practitioner post-mortem (single-source field report — weigh accordingly) traced a first-impression revenue loss after a 10 → 11 upgrade to addAdUnits deferred inside nested pbjs.que pushes, so the first requestBids ran with zero ad units. The upgrade did not cause the bug — it surfaced a latent one. Audit que ordering explicitly.
- Canary against the 10.x baseline. Roll 11.x to a slice of traffic with bid-rate, CPM, and bidRequested-event parity monitoring against 10.x. Watch the console for frozen-ortb2 mutation errors (TypeErrors thrown by event handlers that modify the ortb2 object — see GitHub issue #14632).
The three things the changelog undersells.
Each of these is one line in the release notes and a week of debugging in production.
Media-type validation is two flags, not one.
The headline change — strict rejection of mismatched mediaTypes — is on by default. The second flag, rejectUnknownMediaTypes, is off by default and covers a different hole: bids that declare no mediaType at all, which otherwise silently default to banner. A deliberate posture sets both.
pbjs.setConfig({
auctionOptions: {
// 11.0 default: bids whose mediaType mismatches the
// ad unit's mediaTypes are rejected. Diagnostic opt-out:
rejectInvalidMediaTypes: false,
// OFF by default. When true, also rejects bids that
// declare NO mediaType (which otherwise silently
// default to banner):
rejectUnknownMediaTypes: true
}
}); Slot matching: three removed surfaces, one replacement.
Anyone passing a second argument to setTargetingForGPTAsync breaks at upgrade. The consolidation is genuinely simpler — but only after you find all three places the old functions could hide.
// Before 11.0 — three surfaces, all removed:
// pbjs.setTargetingForGPTAsync(adUnitCodes, customSlotMatching)
// gptPreAuction: { customGptSlotMatching: fn }
// bidViewability: { customMatchFunction: fn }
// 11.0 — one top-level option:
pbjs.setConfig({
customGptSlotMatching: (slot) => (adUnitCode) =>
slot.getAdUnitPath() === adUnitCode ||
slot.getSlotElementId() === adUnitCode
}); The removed events fail silently.
A build referencing a removed module fails loudly at compile time. A listener on addAdUnits, bidAccepted, or seatNonBid fails silently at runtime: the code is valid, the event never fires, and the first sign is a reporting pipeline that quietly flatlines. This is the highest-risk item on the page for revenue-reporting integrity — audit analytics adapters by hand, not by waiting for errors.
Symptoms after upgrading.
If the upgrade already happened and something is wrong, start here. Each row maps an observed symptom to its verified cause.
| Symptom | Likely cause | Fix |
|---|---|---|
| Build fails on an unknown module | The build config references a module removed in 11.0 | Diff the config against the removed list in the table above; remove or replace. |
| Analytics dashboards go quiet after the upgrade — no error anywhere | A listener or analytics adapter depends on addAdUnits, bidAccepted, or seatNonBid, which no longer fire | Remap to auctionInit / beforeRequestBids, bidResponse, and pbsAnalytics; confirm the analytics adapter vendor has shipped an 11.x-compatible version. |
| Bid rate drops for specific bidders; no adapter errors | Strict mediaType validation is rejecting bids whose declared mediaType does not match the ad unit | Read the rejection logs first. Fix ad unit mediaTypes declarations or escalate to the bidder; use rejectInvalidMediaTypes: false only to confirm the diagnosis. |
| First page-load auctions return no bids; later auctions are fine | Initialization-order bug: addAdUnits deferred inside nested que pushes past the first requestBids (field-reported after a 10 → 11 upgrade) | Flatten or reorder the pbjs.que pushes so ad units are registered before the first requestBids call. |
| Console TypeErrors from event handlers ("read only property") | The ortb2 object passed to event handlers is frozen; code mutating it in-flight throws (GitHub issue #14632) | Clone before modifying; move first-party-data writes to setConfig / setBidderConfig instead of event-time mutation. |
| ID modules or storage reads failing where they worked on 10.x | storageControl strict enforcement is blocking undisclosed storage access | Fix the module's storage disclosures; storageControl: { enforcement: 'off' } restores 10.x behavior while you do. |
| Viewability events missing for some ad units | Element linkage failed — the container div id does not match the ad unit code and no adUnit.element was set | Set adUnit.element explicitly for every unit where the id and code diverge. |
The support reality: there is no LTS.
Prebid.org’s documented policy: the previous major version is supported for a minimum of 30 days after a new major ships, and no version older than the previous major is supported at all. No LTS program exists; “minimum 30 days” is the only documented commitment — no end-of-life date for 10.x has been published.
- 2025-07-01 — Prebid.js 10.0.0 released.
- 2026-03-12 — Prebid.js 11.0.0 released; the 30-day minimum clock on 10.x starts.
- ~April 2026 — the documented minimum expires; 10.x is effectively unsupported from here.
- 2026-07-08 — 11.23.0, the current release at validation; minors ship roughly weekly.
What this means for the Adpod go/no-go
“Stay on 10.x” is not a stable option — it means running unsupported code that stops receiving fixes, on a wrapper that touches every auction. The Adpod decision is therefore a real deadline, not a preference.
What this page does not cover.
This is a Prebid.js 10.x → 11.x page, verified against the sources listed below — nothing more.
- Prebid Server (Go and Java) — separately versioned, separately released; its changes are not covered here.
- Prebid Mobile SDK — its own version line (3.x) and release notes.
- The 9 → 10 jump — anyone below 10.x must complete the official pb10-notes list first; this page assumes a clean 10.x baseline.
- Per-bidder adapter behavior changes across the 11.x minor line — weekly releases; validate adapters you depend on against current release notes.
- An official umbrella tracking issue for Prebid 11 migration problems (Prebid 9 had one) is not publicly documented as of validation.
Frequently asked questions.
The questions upgraders actually search, answered in this page’s own words. Each is covered in depth above.
Is Prebid.js 10.x still supported?
Effectively no. Prebid.org has no LTS program; its documented policy is to support the previous major version for a minimum of 30 days after a new major ships. Prebid.js 11.0 was released March 12, 2026, so 10.x has been past that minimum since roughly April 2026. No end-of-life date is published — "minimum 30 days" is the only documented commitment.
Why did bid volume drop after upgrading to Prebid.js 11?
The most common cause is strict mediaType validation: 11.0 rejects, by default, any bid whose declared mediaType does not match the ad unit’s mediaTypes. Check bid-rejection logs before anything else. auctionOptions.rejectInvalidMediaTypes: false restores the old behavior, but treat it as a diagnostic, not a fix. A separate field-reported cause is initialization ordering: addAdUnits deferred inside nested pbjs.que pushes so the first auction runs with zero ad units.
What replaces the addAdUnits, bidAccepted, and seatNonBid events?
Per the official 11.0 notes: use auctionInit or beforeRequestBids instead of addAdUnits, bidResponse instead of bidAccepted, and pbsAnalytics instead of seatNonBid. The failure mode is silent — listeners on removed events simply stop firing — so audit analytics adapters explicitly rather than waiting for an error.
Does Prebid.js 11 still support Adpod or PAAPI?
No. 11.0 removed the entire Adpod suite (adpod, categoryTranslation, dfpAdpod, gamAdpod, freeWheelAdserverVideo, dfpAdServerVideo) and all PAAPI modules (paapi, paapiForGpt, topLevelPaapi), with no replacement. CTV and long-form publishers building pods through Prebid.js face an architecture decision, not a migration step.
Do I need to redo the userId-to-EIDs migration for Prebid.js 11?
No — that was a 10.0 change, not an 11.0 change. bid.userId stopped being populated in Prebid.js 10.0; consumers read userIdAsEids or ortb2.user.ext.eids instead. If you are cleanly on 10.x you have already absorbed it. It belongs in pre-flight only as a confirmation, and as a required first step for anyone jumping from 9.x.
Upgrading a wrapper with revenue attached?
A Prebid major upgrade is a policy migration, not a version bump: events, validation posture, storage enforcement, and monitoring all move at once. Scope the rollout before the rollout scopes you.