Server-side social embeds for WordPress: the cookie-free pattern.

Every social embed loads the platform's tracking on every visitor. A server-side aggregator does the same job — Instagram, X, TikTok, LinkedIn, more — without the cookies.

Every Instagram, X, TikTok, or LinkedIn embed on a WordPress site loads that platform's full tracking infrastructure on the visitor's browser, regardless of whether they have an account on the platform. The standard embed pattern is a privacy liability. The alternative — fetching content server-side and rendering it as static HTML — takes the same content to the page without any of the cookies. The pattern is the same for every social platform with an API.

The default social embed for a WordPress page — Instagram, X, TikTok, LinkedIn, Threads, Facebook — works the same way regardless of which platform it points at. The page loads the platform’s JavaScript SDK, which renders the post content inside an iframe and connects to the platform’s servers in real time. The user experience looks fine. The privacy footprint is dramatically different from a static image: the platform now sees the user’s visit, can correlate it with the user’s identity on that platform if they have one, and drops the tracking cookies that come with any of its content. For a site trying to operate without a consent banner, social embeds are usually one of the largest remaining items on the list.

The server-side aggregation pattern solves this for every social platform that has an API. Your server fetches content on a schedule, caches it locally, and renders it as static HTML on the page. No third-party JavaScript, no iframes pointing at instagram.com or x.com or tiktok.com, no cookies dropped on page load. The visitor sees the same social posts; the platform never knows about the visit.

How the standard embed leaks.

What happens when a typical social embed loads on a WordPress page, taking Instagram as the example (every other platform follows the same pattern):

  • The page includes a script tag pointing to the platform’s embed JS — e.g. www.instagram.com/embed.js, platform.twitter.com/widgets.js.
  • That script runs on page load, regardless of whether the visitor has an account on the platform.
  • The script makes requests to the platform’s domain to fetch the post content.
  • The platform’s cookies are dropped on the visitor’s browser as part of those requests — ig_did, datr, guest_id, and others depending on the user’s existing cookie state.
  • The post renders inside an iframe from the platform’s domain.
  • If the user is logged into the platform in another tab, the visit is correlated with their identity and added to the platform’s behavior graph.

None of this requires the user to interact with the embed. It all happens on page load. From a GDPR perspective, the site has shared the user’s data with a third party without consent before the user has seen anything.

What the server-side pattern does.

The architecture is the same regardless of which platform you’re pulling from:

  1. A scheduled job (WordPress cron, server cron, GitHub Action, whatever fits) runs every N hours and calls the platform’s API to fetch the latest posts from the account or hashtag you’re displaying.
  2. The job stores the post data locally — caption, media URL, post URL, timestamp — in WordPress post meta, a custom post type, or a custom table.
  3. The job downloads the post media to your own media library, so the image src on your page isn’t a hot-link to the platform’s CDN.
  4. The page template renders the cached data as static HTML — an image, a caption, a link to the original post on the platform. No iframes, no third-party JavaScript.
  5. The link to the original post is a normal <a href>. Clicking it sends the user to the platform, where their browser does whatever it normally does — but that’s an explicit user action, not a load-time privacy leak.

The visitor sees social content. The platform sees nothing.

What this requires per platform.

The pattern is the same; the API specifics vary. The high-level state of each:

  • Instagram — Instagram Graph API. Requires an Instagram Business or Creator account, a Meta Developer App, and a long-lived access token (refresh every 60 days, automatable). The most stable social API to build against; the main constraint is the Business-account requirement.
  • X (Twitter) — X API. The free tier is now read-limited; meaningful use requires a paid Basic or Pro tier. The most expensive of these to maintain, and the API’s posture has been the least stable. Costs and access tiers should be checked before committing.
  • TikTok — Display API. Free, but the OAuth flow is the most fiddly; tokens need periodic re-auth that’s harder to fully automate. Good fit when TikTok content is genuinely part of the site’s story; overkill otherwise.
  • LinkedIn — Marketing Developer Platform. Company posts API works, but app review is slow and the rate limits are tight. Workable, but the heaviest setup of the group.
  • Facebook — Same Meta infrastructure as Instagram. The Page Posts API is straightforward if the Page is yours. Same Developer App and token flow.
  • Threads — Threads API launched in 2024. Same Meta infrastructure pattern. The API surface is smaller than Instagram’s but covers what’s needed for a server-side feed.

Each is more setup than installing an embed plugin. Each is a one-time setup — once the token’s in place, the scheduled job runs forever, with periodic token refresh on platforms that require it.

The trade-offs.

What you gain:

  • No third-party cookies on page load
  • No third-party JavaScript — faster page render, smaller transfer size, no Core Web Vitals impact from the embed
  • Content stays on the page even if the platform is down or rate-limits
  • Customizable rendering (style, layout, what to show) without fighting the platform’s iframe
  • The privacy posture lets you drop or simplify the consent banner

What you lose:

  • The live feel of the iframe embed — the data is as fresh as the last cron run, not real-time. Usually fine; tune the interval to taste.
  • Embed features that depend on the platform’s JS (in-page likes, in-page replies, video autoplay)
  • An hour or two of API plumbing per platform vs. a one-line embed

For most marketing-site use cases (display the last 6 posts on the homepage; show the latest from a specific hashtag; pull testimonials), the trade-off is clean: the things you lose aren’t things visitors expect from a feed, and the things you gain are real privacy and performance wins.

The same pattern, beyond social.

The architecture isn’t social-specific. Anywhere the site is pulling content from a third party via an embed, the same pattern applies:

  • Google Reviews — fetch via the Places API, cache locally, render as static HTML with Schema.org Review markup. Same approach, different audience, and a meaningful SEO upside that social embeds don’t have. Covered separately in server-side Google Reviews for WordPress.
  • Third-party review aggregators (G2, Capterra, Trustpilot) — most have public APIs that allow the same fetch-and-cache flow.
  • YouTube embeds — different fix; covered in hosting WordPress video without YouTube’s cookies.

Each one trades a small amount of dynamic functionality for a meaningful privacy improvement. For sites trying to reduce or eliminate the consent banner, working through these one at a time is the path. See privacy built into the platform for the full pattern.

Let's talk about what you're building

No proposals. No pitch decks. Just a conversation about your project and whether I'm the right fit to build it.

Start a Conversation