Back to Colophon
Back to Colophon

Standard X embeds load tracking scripts and set cookies on every page view. This site uses astro-tweet to fetch posts at build time and render them as static HTML. X never knows when someone views the embedded post.

#privacy#embeds#astro

The standard embed problem#

X’s official embed loads platform.twitter.com/widgets.js in every visitor’s browser. That script:

  • Sets tracking cookies
  • Phones home to X’s analytics
  • Loads additional resources
  • Executes arbitrary JavaScript on your page

YouTube has youtube-nocookie.com as a privacy alternative. X doesn’t offer anything equivalent.

Build-time fetching#

This site uses astro-tweet, which takes a different approach. Instead of loading X’s widget at runtime, it fetches post data during the Astro build:

Build time: Your server → X syndication API → Static HTML
Page view:  Visitor → Your static HTML (no X connection)

The syndication API is the same endpoint X’s widget uses internally. The difference is when and where it runs.

How it works#

X’s public syndication endpoint at cdn.syndication.twimg.com/tweet-result returns JSON with the post content, author info, media, and engagement counts. The astro-tweet package calls this once per post during build, then renders the response to HTML.

The authentication is just a hash of the post ID:

typescript
function getToken(id: string) {
  return ((Number(id) / 1e15) * Math.PI)
    .toString(6 ** 2)
    .replace(/(0+|\.)/g, "");
}

No API keys, no OAuth, no rate limits for reasonable usage.

Example#

Here’s a post rendered this way:

View source on that. It’s pure HTML and CSS. No iframes, no external scripts, no tracking pixels.

Trade-offs#

What you lose:

  • Live engagement counts - likes and retweets freeze at build time
  • Deleted post handling - if the author deletes it, yours stays until you rebuild
  • Native interactivity - no “like from embed” functionality

What you keep:

  • Full visual fidelity (I style it to match this site’s aesthetic)
  • All media, links, and author info
  • Zero JavaScript for the embed
  • Complete privacy for your visitors

Comparison#

ApproachTrackingJS RequiredLive Data
astro-tweet (this site)NoneNoStatic
Standard X embedFullYesYes
YouTube nocookieSomeYesYes

Build-time fetching is actually more private than YouTube’s nocookie option, which still loads Google’s player code in the browser.

Usage#

astro
import Tweet from '../components/Tweet.astro';

<Tweet id="1694368034755096857" />
// or
<Tweet id="https://x.com/tonyseets/status/1694368034755096857" />

The component accepts either a bare ID or a full URL.

Standard X embeds load tracking scripts and set cookies on every page view. This site uses astro-tweet to fetch posts at build time and render them as static HTML. X never knows when someone views the embedded post.