Lazy-load social SDKs only when an embed is present#928
Merged
Conversation
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. Fixes #926
3 tasks
GaryJones
added a commit
that referenced
this pull request
Jun 26, 2026
develop's lazy-load social SDK work (#928) rewrote src/react/utils/utils.js and its test, which overlapped with this branch's reformat to tabs and the relocation of getImageSize. The two conflicted files are resolved in favour of develop's logic, onto which the branch's mechanical layer is reapplied: getImageSize is re-added (Editor/utils.js no longer exists here and EditorContainer imports it from utils/utils), the files are reformatted to tabs, and the manual lint fixes for getNewestEntry and getScrollToId JSDoc, the optional catch binding and the duplicated test title are restored. lint:js is back to only the eleven known jsx-a11y errors and all 72 unit tests pass, including the five new embed SDK tests from develop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.
The previous behaviour gated on
is_viewing_liveblog_post()but then enqueued every SDK inself::$sdksunconditionally. The only escape hatch was emptying the list via theliveblog_embed_sdksfilter, which disables enhanced rendering globally rather than loading only what is needed.This change moves SDK loading client-side and on demand. The plugin no longer enqueues any SDK directly; instead it exposes the (still filterable) provider URL map to the front-end app via
liveblog_settings. The React entry renderer already runstriggerOembedLoad()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
liveblog_embed_sdksfilter is preserved, so the documented__return_empty_arrayopt-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.jsexposes 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 throughesc_url()on a server-side enqueue, but would break a client-injectedsrc, so it is now stored un-encoded.Test plan
composer test:unit(newEntryEmbedSdksTestcovers the provider list, the un-encoded Facebook URL, settings injection, and thatload()registers the settings hook rather than enqueuing).npm test(updatedtriggerOembedLoadtests cover on-demand injection, single-injection across entries, and the no-markup / no-config cases).connect.facebook.net,platform.twitter.com,instagram.comorembed.reddit.comrequests are made. Add a single tweet and confirm only the Twitter SDK loads, including in a newly published entry.Fixes #926