Skip to content

Lazy-load social SDKs only when an embed is present (2.x)#929

Merged
GaryJones merged 1 commit into
2.xfrom
GaryJones/2.x-lazy-load-embed-sdks
Jun 26, 2026
Merged

Lazy-load social SDKs only when an embed is present (2.x)#929
GaryJones merged 1 commit into
2.xfrom
GaryJones/2.x-lazy-load-embed-sdks

Conversation

@GaryJones

Copy link
Copy Markdown
Contributor

Summary

Liveblog enqueued the Facebook, Twitter/X, Instagram and Reddit JavaScript SDKs on every Liveblog-enabled post, regardless of whether the post or its entries actually contained an embed from any of those services. As reported in #926, this meant visitors' browsers contacted four third-party domains on every Liveblog page, leaking request data to platforms whose content was never displayed, adding avoidable page-load overhead, and complicating Content Security Policy and consent compliance. A site using a single provider, or no social embeds at all, still paid the cost of all four.

This is the backport of #928 (merged to develop) onto the 2.x architecture. The behaviour and front-end loader are identical; only the PHP wiring differs to fit 2.x.

On 2.x the SDK logic lives in AssetManager. Rather than enqueuing every SDK on wp_enqueue_scripts, the plugin now passes the (still filterable) provider URL map to the front-end app through liveblog_settings. The React entry renderer already runs triggerOembedLoad() on every entry's mount and update, so that became the natural hook: for each provider it detects provider-specific embed markup, and if found either re-processes the entry (when the SDK is already present) or injects the SDK once. Because it runs per entry, it correctly handles embeds arriving in entries polled after the initial page load, not just those present on first render.

The now-unused enqueue_embed_sdks() and add_async_to_embed_sdks() methods and their hook registrations in PluginBootstrapper have been removed; init_embed_sdks() is retained, as it applies the liveblog_embed_sdks filter and populates the map now consumed by the front-end. The filter's __return_empty_array opt-out and per-provider removal continue to work and now also gate lazy loading.

A known limitation worth a reviewer's eye

Reddit's widgets.js exposes no reliable client-side re-process API; it only scans the document when it first loads. A Reddit embed arriving in an entry polled after the SDK has already loaded therefore won't auto-render. This is not a regression (Reddit was never re-processed client-side before either), but it is a gap if true live-update parity for Reddit is wanted later.

Note on the Facebook URL

The default Facebook SDK URL previously carried an HTML-encoded & in its hash. That was harmless when passed through esc_url() on a server-side enqueue, but would break a client-injected src, so it is now stored un-encoded.

Test plan

  • Integration tests: composer test:integration (rewritten EmbedSdksTest asserts the SDKs are no longer enqueued on a liveblog post and that the SDK map is exposed in the localised front-end settings, plus filter customisation and the empty-array opt-out). Verified locally: 5 tests, 14 assertions passing.
  • JS unit tests: npm test (updated triggerOembedLoad tests cover on-demand injection, single-injection across entries, and the no-markup / no-config cases). Verified locally: 16 tests passing.
  • Manual: enable Liveblog on a post with no social embeds and confirm no connect.facebook.net, platform.twitter.com, instagram.com or embed.reddit.com requests are made. Add a single tweet and confirm only the Twitter SDK loads, including in a newly published entry.

Fixes #926

Liveblog enqueued the Facebook, Twitter/X, Instagram and Reddit
JavaScript SDKs on every Liveblog-enabled post, even when no embed
from any of those services was present. This made visitors' browsers
contact four third-party domains unnecessarily, leaking request data,
adding page-load overhead and complicating CSP and consent handling.

Stop enqueuing the SDKs server-side. Instead, expose the (still
filterable) provider URL map to the front-end and lazy-load each SDK
client-side the first time an entry containing that provider's embed
markup is rendered. Because this runs per entry on mount and update,
it also covers embeds arriving in entries polled after page load.

Backports the develop-branch fix (#928) to 2.x.

Fixes #926
@GaryJones GaryJones requested a review from a team as a code owner June 26, 2026 13:45
@GaryJones GaryJones merged commit 6cb015c into 2.x Jun 26, 2026
10 checks passed
@GaryJones GaryJones deleted the GaryJones/2.x-lazy-load-embed-sdks branch June 26, 2026 13:55
@GaryJones GaryJones added this to the 2.0 milestone Jun 26, 2026
@GaryJones GaryJones self-assigned this Jun 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant