Skip to content

Add client-side bidder support for Prebid.js#472

Merged
ChristianPavilonis merged 5 commits into
mainfrom
feature/prebid-client-allow
Mar 16, 2026
Merged

Add client-side bidder support for Prebid.js#472
ChristianPavilonis merged 5 commits into
mainfrom
feature/prebid-client-allow

Conversation

@ChristianPavilonis
Copy link
Copy Markdown
Collaborator

@ChristianPavilonis ChristianPavilonis commented Mar 11, 2026

Summary

  • Allow specific Prebid.js bidders to run client-side in the browser instead of routing all bidders through the server-side auction. Some adapters (e.g. Magnite/Rubicon) do not work well with Prebid Server.
  • Adds a new client_side_bidders config field — bidders in this list stay as standalone native Prebid.js bids and are not absorbed into the trustedServer adapter.
  • Adds a build-time adapter selection system (TSJS_PREBID_ADAPTERS env var) so operators can control which native Prebid.js adapters are bundled without code changes.
  • Backward compatible: an empty list preserves current behavior (all bidders go server-side).

Auction flow

flowchart TD
    A["Publisher Page<br/>pbjs.requestBids()"] --> B["requestBids Shim<br/>(tsjs-prebid)"]
    B --> C{"Is bidder in<br/>clientSideBidders?"}
    C -- "Yes (e.g. rubicon)" --> D["Leave as standalone bid<br/>Native Prebid.js adapter"]
    C -- "No (e.g. kargo, appnexus)" --> E["Absorb into trustedServer<br/>bidderParams"]
    E --> F["POST /auction<br/>Trusted Server Orchestrator"]
    F --> G["Prebid Server (PBS)<br/>OpenRTB 2.x auction"]
    G --> H["Server-side bids returned<br/>(kargo, appnexus, etc.)"]
    D --> I["Client-side bid<br/>(rubicon via rubiconBidAdapter.js)"]
    H --> J["Prebid.js auction<br/>All bids compete"]
    I --> J
    J --> K["Winning bid rendered"]

    style C fill:#f9f,stroke:#333
    style D fill:#bfb,stroke:#333
    style E fill:#bbf,stroke:#333
Loading

Configuration example

[integrations.prebid]
bidders = ["kargo", "appnexus", "openx"]         # server-side via PBS
client_side_bidders = ["rubicon"]                  # native browser adapters

Changes

File Change
crates/common/src/integrations/prebid.rs Added client_side_bidders: Vec<String> to PrebidIntegrationConfig with #[serde(default, deserialize_with)]; added field to InjectedPrebidClientConfig with skip_serializing_if; added duplicate-bidder warning when a bidder appears in both lists; updated base_config() test helper; added 2 tests for head injector serialization
crates/js/lib/src/integrations/prebid/index.ts Imports generated adapter barrel file (_adapters.generated.ts) and adapterManager; added clientSideBidders to InjectedPrebidConfig interface; reads config into a Set; skips client-side bidders when building bidderParams for trustedServer; validates that each client-side bidder has a registered adapter at init
crates/js/lib/src/integrations/prebid/_adapters.generated.ts New generated file — barrel of import statements for each adapter listed in TSJS_PREBID_ADAPTERS (defaults to rubicon)
crates/js/lib/build-all.mjs Added generatePrebidAdapters() that reads TSJS_PREBID_ADAPTERS env var, validates adapter modules exist in prebid.js/modules/, and writes _adapters.generated.ts; added Vite resolve.alias for prebid.js/src/adapterManager.js
crates/js/lib/vitest.config.ts Added resolve.alias for prebid.js/src/adapterManager.js so tests can resolve the module
crates/js/lib/test/integrations/prebid/index.test.ts Added mocks for _adapters.generated.ts and adapterManager; added 8 new tests covering client-side bidder edge cases
crates/js/lib/package-lock.json Dependency updates from prebid.js module resolution
trusted-server.toml Moved rubicon from bidders to new client_side_bidders; added documentation comment

Closes

Closes #471
Closes #463

Known limitations

  • Adding a new client-side bidder requires setting TSJS_PREBID_ADAPTERS at build time (e.g. TSJS_PREBID_ADAPTERS=rubicon,appnexus) and rebuilding the JS bundle — no code changes needed.
  • The bidders and client_side_bidders lists are independent — the operator manages both explicitly. A warning is logged at startup if a bidder appears in both.

Test plan

  • cargo test --workspace
  • cargo clippy --all-targets --all-features -- -D warnings
  • cargo fmt --all -- --check
  • JS tests: cd crates/js/lib && npx vitest run
  • JS format: cd crates/js/lib && npm run format
  • Docs format: cd docs && npm run format — pre-existing: prettier not installed in docs/
  • WASM build: cargo build --bin trusted-server-fastly --release --target wasm32-wasip1
  • Manual testing via fastly compute serve

Checklist

  • Changes follow CLAUDE.md conventions
  • No unwrap() in production code — use expect("should ...")
  • Uses tracing macros (not println!)
  • New code has tests
  • No secrets or credentials committed

@ChristianPavilonis ChristianPavilonis self-assigned this Mar 11, 2026
@ChristianPavilonis ChristianPavilonis marked this pull request as ready for review March 11, 2026 21:52
Copy link
Copy Markdown
Collaborator

@prk-Jr prk-Jr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks good

ChristianPavilonis and others added 5 commits March 16, 2026 11:24
… for Prebid

Add support for running specific Prebid.js bidders client-side in the
browser instead of routing all bidders through the server-side auction.

Rust changes:
- Add client_side_bidders field to PrebidIntegrationConfig
- Serialize clientSideBidders into injected head config
- Warn when a bidder appears in both bidders and client_side_bidders

JS changes:
- requestBids shim skips client-side bidders from trustedServer bidderParams
- Build-time adapter generation via TSJS_PREBID_ADAPTERS env var
- Runtime validation that client-side bidders have adapters loaded
- Vite resolve alias for prebid.js/src/adapterManager.js (not in
  package exports map)

Closes #471
- Add Vite resolve.alias for prebid.js/src/adapterManager.js in both
  vitest.config.ts and build-all.mjs since the prebid.js package exports
  map does not expose internal src/ paths
- Wrap getBidAdapter() validation in try-catch for defensive robustness
- Fix doc comment ordering so client_side_bidders and
  bid_param_zone_overrides each have their own doc block
- Run prettier to fix format-typescript CI check
@ChristianPavilonis ChristianPavilonis force-pushed the feature/prebid-client-allow branch from 11f1f08 to 6ac03a6 Compare March 16, 2026 16:24
@ChristianPavilonis ChristianPavilonis merged commit 2170aa7 into main Mar 16, 2026
10 checks passed
@aram356 aram356 deleted the feature/prebid-client-allow branch March 19, 2026 16:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants