diff --git a/.claude/settings.json b/.claude/settings.json
index c4261ade..95f403b4 100644
--- a/.claude/settings.json
+++ b/.claude/settings.json
@@ -10,22 +10,22 @@
"Bash(tree:*)",
"Bash(wc:*)",
"Bash(which:*)",
-
"Bash(npm ci:*)",
"Bash(npm run:*)",
"Bash(npm test:*)",
-
"Bash(cargo build:*)",
"Bash(cargo check:*)",
"Bash(cargo clippy:*)",
"Bash(cargo fmt:*)",
"Bash(cargo metadata:*)",
"Bash(cargo test:*)",
-
"Bash(git branch:*)",
"Bash(git diff:*)",
"Bash(git log:*)",
- "Bash(git status:*)"
+ "Bash(git status:*)",
+ "mcp__plugin_chrome-devtools-mcp_chrome-devtools__new_page",
+ "mcp__plugin_chrome-devtools-mcp_chrome-devtools__performance_stop_trace",
+ "mcp__plugin_chrome-devtools-mcp_chrome-devtools__evaluate_script"
]
}
}
diff --git a/CLAUDE.md b/CLAUDE.md
index abf6e896..9ad1845c 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -237,9 +237,10 @@ IntegrationRegistration::builder(ID)
.build()
```
-- Integration IDs match JS directory names: `prebid`, `lockr`, `permutive`, `datadome`, `didomi`, `testlight`.
+- Integration IDs match JS directory names: `prebid` (deferred), `lockr`, `permutive`, `datadome`, `didomi`, `testlight`.
- `creative` is JS-only (no Rust registration); `nextjs`, `aps`, `adserver_mock` are Rust-only.
-- `IntegrationRegistry::js_module_ids()` maps registered integrations to JS module names.
+- Integrations opt into deferred loading via `.with_deferred_js()` on the registration builder. Deferred modules are served as separate `"#
+ r#""#
)]
}
}
@@ -1232,13 +1233,17 @@ template = "{{client_ip}}:{{user_agent}}"
"Unified bundle should be injected"
);
assert!(
- !processed.contains("prebid.min.js"),
- "Prebid script should be removed when auto-config is enabled"
+ !processed.contains("cdn.prebid.org/prebid.min.js"),
+ "Publisher prebid script should be removed when auto-config is enabled"
);
assert!(
!processed.contains("cdn.prebid.org/prebid.js"),
"Prebid preload should be removed when auto-config is enabled"
);
+ assert!(
+ processed.contains("tsjs-prebid.min.js"),
+ "Deferred prebid bundle should be injected"
+ );
}
#[test]
diff --git a/crates/common/src/integrations/registry.rs b/crates/common/src/integrations/registry.rs
index 07fec408..158a1e29 100644
--- a/crates/common/src/integrations/registry.rs
+++ b/crates/common/src/integrations/registry.rs
@@ -390,6 +390,7 @@ pub trait IntegrationHeadInjector: Send + Sync {
/// Registration payload returned by integration builders.
pub struct IntegrationRegistration {
pub integration_id: &'static str,
+ pub js_deferred: bool,
pub proxies: Vec>,
pub attribute_rewriters: Vec>,
pub script_rewriters: Vec>,
@@ -413,6 +414,7 @@ impl IntegrationRegistrationBuilder {
Self {
registration: IntegrationRegistration {
integration_id,
+ js_deferred: false,
proxies: Vec::new(),
attribute_rewriters: Vec::new(),
script_rewriters: Vec::new(),
@@ -458,6 +460,14 @@ impl IntegrationRegistrationBuilder {
self
}
+ /// Mark this integration's JS module for deferred loading via
+ /// `",
+ tsjs_deferred_script_src(module_id)
+ )
+}
+
+/// Generate all deferred `