# Prebid.js 10 → 11 Migration

> Every verified breaking change in Prebid.js 11.0 — removed modules, dead events, strict mediaType checks — with an ordered, primary-sourced migration checklist.

- Canonical: https://nofluffadvisory.com/standards/prebid-11-migration/
- Published: 2026-07-13
- Standards last validated: 2026-07-13

---

*Standards & Protocols · Deep dive*

Validated July 2026 · against 11.23.0

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.

*Figure: The migration spine: audit before touching code, make the five changes, prove parity against the 10.x baseline.*

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.

**Version status at validation (July 2026)**

- **Prebid.js 11.0** — released Mar 12, 2026 [status: ga]
- **11.x line** — 11.23.0 · Jul 8, 2026 [status: live]
- **Prebid.js 10.x** — past the 30-day support minimum [status: deprecating]

## 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.

*The damage 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](https://github.com/prebid/Prebid.js/releases/tag/11.0.0) |
| 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](https://github.com/prebid/Prebid.js/releases/tag/11.0.0) |
| 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](https://docs.prebid.org/dev-docs/pb11-notes.html) |
| 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](https://docs.prebid.org/dev-docs/pb11-notes.html) |
| 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](https://docs.prebid.org/dev-docs/pb11-notes.html) |
| 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](https://docs.prebid.org/dev-docs/pb11-notes.html) |
| 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](https://docs.prebid.org/dev-docs/pb11-notes.html) |
| 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](https://docs.prebid.org/dev-docs/pb11-notes.html) |
| 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](https://github.com/prebid/Prebid.js/releases/tag/11.0.0) |

**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 spine*

## 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.

1. **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.
2. **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.
3. **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.

1. **Unify slot matching on customGptSlotMatching.** Replace the setTargetingForGPTAsync second argument, gptPreAuction.customGptSlotMatching, and bidViewability.customMatchFunction with the single top-level customGptSlotMatching setConfig option.
2. **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.
3. **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.
4. **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.
5. **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.

1. **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.
2. **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).

*Nuance*

## 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.

**auctionOptions — the two 11.0 validation flags** (per pb11-notes)

```json
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.

**customGptSlotMatching — the unified option** (illustrative shape — validate against pb11-notes)

```json
// 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.

*Troubleshooting*

## 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 clock*

## 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.

*Honest scope*

## 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.

*Plain answers*

## 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.

*Validate, don’t assume*

## Related materials and primary sources.

- [Prebid & Header Bidding — the full guide](https://nofluffadvisory.com/standards/prebid-header-bidding/)
- [Core AdTech Standards](https://nofluffadvisory.com/standards/core-adtech-standards/)
- [Privacy & Consent Standards](https://nofluffadvisory.com/standards/privacy-consent-platform-apis/)
- [Video & Mobile Ad Delivery](https://nofluffadvisory.com/standards/video-mobile-ad-delivery/)
- [CTV, Streaming & Live Events](https://nofluffadvisory.com/standards/ctv-streaming-live-event-advertising/)

### Primary sources to validate (8 sources)

- [Prebid.js 11.0.0 release notes (GitHub)](https://github.com/prebid/Prebid.js/releases/tag/11.0.0) — Prebid.org / prebid/Prebid.js. Official GitHub; confidence: primary; checked 2026-07-12. The authoritative 11.0.0 changelog: removed modules and adapters, removed events, mediaType validation, storageControl default, viewability overhaul, DNT removal. Supports: Removed modules, Removed adapters, Release date (2026-03-12).
- [Prebid.js 11.0 release notes (docs.prebid.org)](https://docs.prebid.org/dev-docs/pb11-notes.html) — Prebid.org. Official docs; confidence: primary; checked 2026-07-12. The official developer-facing 11.0 notes: event replacements, customGptSlotMatching consolidation, adUnit.element and viewability, auctionOptions flags, storageControl enforcement. Supports: Event remapping, Slot matching, mediaType flags, Viewability.
- [Prebid.js 10.0 release notes (docs.prebid.org)](https://docs.prebid.org/dev-docs/pb10-notes.html) — Prebid.org. Official docs; confidence: primary; checked 2026-07-12. The 10.0 prerequisites this page assumes are absorbed: bid.userId removal in favor of EIDs, schain relocation, gpid. Required reading for anyone jumping from 9.x. Supports: Pre-flight prerequisites, 9 → 11 path.
- [Prebid.js 10.0.0 release (GitHub)](https://github.com/prebid/Prebid.js/releases/tag/10.0.0) — Prebid.org / prebid/Prebid.js. Official GitHub; confidence: primary; checked 2026-07-12. Confirms the 10.0.0 release date (2025-07-01) used in the support-window arithmetic. Supports: Timeline.
- [PREBID_VERSIONING_DEPRECATION.md](https://github.com/prebid/Prebid.js/blob/master/PREBID_VERSIONING_DEPRECATION.md) — Prebid.org / prebid/Prebid.js. Official GitHub; confidence: primary; checked 2026-07-12. The versioning and deprecation policy: previous major supported a minimum of 30 days after a new major; majors no more than once per 30 days; the deprecation process (issue → discussion → announcement → approvals → console warning). Supports: No-LTS claim, Support window.
- [Prebid.js FAQ (docs.prebid.org)](https://docs.prebid.org/dev-docs/faq.html) — Prebid.org. Official docs; confidence: primary; checked 2026-07-12. States that Prebid.org does not support versions older than the previous major — the second leg of the support-reality claim. Supports: Support policy.
- [Prebid.js release history (GitHub)](https://github.com/prebid/Prebid.js/releases) — Prebid.org / prebid/Prebid.js. Official GitHub; confidence: primary; checked 2026-07-12. Confirms 11.23.0 (2026-07-08) as the current release at validation and the roughly weekly minor cadence. Supports: Current version, Cadence.
- [Issue #14632 — frozen ortb2 object in event handlers](https://github.com/prebid/prebid.js/issues/14632) — prebid/Prebid.js (GitHub issues). Official GitHub; confidence: supporting; checked 2026-07-12. Filed 2026-03-23: the ortb2 object passed to event handlers is frozen; code mutating it throws. The source of the TypeError symptom row. Supports: Troubleshooting, frozen-ortb2 symptom.

> Platform capabilities and naming change quickly. Last validated: 2026-07-13. Check current documentation before implementation. Version-stamped page: validated against Prebid.js 11.23.0 (released July 8, 2026) and the official 11.0 release notes. Prebid.js ships minor releases roughly weekly — validate current release notes before executing this checklist.
