You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make GTM inline script accumulation respect IntegrationScriptContext::max_buffered_script_bytes, supplied from HtmlProcessorConfig::max_buffered_body_bytes (the publisher's configured buffer limit).
GoogleTagManagerIntegration::rewrite currently appends matching script fragments without reading that limit. Once a fragment contains a full GTM or GA marker, later fragments can accumulate up to the full text-node size. This also affects first-party inline scripts containing an analytics reference.
Next.js already enforces the same limit in nextjs/rsc_stream.rs::capture_fragment with FragmentState::{Idle, Buffering, BypassUntilLast}. When a script exceeds the limit, it restores buffered text and passes subsequent fragments through until the text node ends.
This is pre-existing behavior. PR #1179 makes GTM accumulation document-local to prevent cross-request residue; it does not bound that accumulation. The follow-up was requested in the sandbox lifecycle review and is deliberately separate from that PR.
Proposed approach
Apply equivalent bounded fragment capture to GTM, reusing or extracting the Next.js mechanism if appropriate. Keep the state in IntegrationDocumentState, preserve GTM's cheap gate for unrelated scripts, and restore every suppressed fragment in source order on overflow before bypassing rewriting for the rest of that text node. Avoid introducing a new configuration field.
Coordinate with #1208, which tracks overlapping script rewriters and GTM fragment ordering; this issue specifically tracks enforcing the configured accumulation limit.
Done when
GTM reads max_buffered_script_bytes and does not keep accumulating a text node beyond the limit.
Overflow restores all previously suppressed text and emits the current and remaining fragments unchanged, without truncation, duplication, or reordering.
A completed oversized script in a single callback passes through unchanged; scripts at or below the limit retain normal rewriting behavior.
Bypass resets at the end of the text node, allowing the next script to be rewritten normally.
State stays document-local, and interruption while buffering or bypassing leaves no residue for a second document through the same retained registry.
Tests cover exact-limit and over-limit inputs, overflow on intermediate and final fragments, single-callback oversized input, markers split across fragments, unrelated scripts, multiple scripts in one document, and overlapping Next.js/GTM selectors.
Existing GTM and Next.js fragment and interrupted-document regressions pass.
Affected area
HTML processing / JS injection
Relevant files: crates/trusted-server-core/src/integrations/google_tag_manager.rs, crates/trusted-server-core/src/integrations/nextjs/rsc_stream.rs, and crates/trusted-server-core/src/integrations/registry.rs.
Description
Make GTM inline script accumulation respect
IntegrationScriptContext::max_buffered_script_bytes, supplied fromHtmlProcessorConfig::max_buffered_body_bytes(the publisher's configured buffer limit).GoogleTagManagerIntegration::rewritecurrently appends matching script fragments without reading that limit. Once a fragment contains a full GTM or GA marker, later fragments can accumulate up to the full text-node size. This also affects first-party inline scripts containing an analytics reference.Next.js already enforces the same limit in
nextjs/rsc_stream.rs::capture_fragmentwithFragmentState::{Idle, Buffering, BypassUntilLast}. When a script exceeds the limit, it restores buffered text and passes subsequent fragments through until the text node ends.This is pre-existing behavior. PR #1179 makes GTM accumulation document-local to prevent cross-request residue; it does not bound that accumulation. The follow-up was requested in the sandbox lifecycle review and is deliberately separate from that PR.
Proposed approach
Apply equivalent bounded fragment capture to GTM, reusing or extracting the Next.js mechanism if appropriate. Keep the state in
IntegrationDocumentState, preserve GTM's cheap gate for unrelated scripts, and restore every suppressed fragment in source order on overflow before bypassing rewriting for the rest of that text node. Avoid introducing a new configuration field.Coordinate with #1208, which tracks overlapping script rewriters and GTM fragment ordering; this issue specifically tracks enforcing the configured accumulation limit.
Done when
max_buffered_script_bytesand does not keep accumulating a text node beyond the limit.Affected area
HTML processing / JS injection
Relevant files:
crates/trusted-server-core/src/integrations/google_tag_manager.rs,crates/trusted-server-core/src/integrations/nextjs/rsc_stream.rs, andcrates/trusted-server-core/src/integrations/registry.rs.