Back to blog
Tutorial

How to Fix X/Twitter Embeds Not Working on Your Website

Tamim
April 15, 2026
8 min read

You pasted the embed code from X onto your landing page. It worked fine on your machine. You shipped it. Then someone messages you: "Hey, your testimonials section is just a white box."

You check on your phone. It loads. You check on desktop. Also loads. But your visitor is staring at nothing. Or maybe you are the one staring at nothing — the embed worked yesterday and today it is gone.

This is the single most common issue founders hit when trying to display social proof from X in 2026. The causes range from trivial to unfixable, and the internet is full of outdated advice that no longer applies after the Twitter-to-X migration.

This guide covers every known fix, in order from simplest to most structural. If you just want the embed to work right now, start from the top. If you have already tried the basics, skip to the section that matches your symptoms.


Fix 1: Check the URL Domain (x.com vs twitter.com)

This is the first thing to try because it is the most common cause and takes 10 seconds to fix.

When Twitter rebranded to X, the domain changed from twitter.com to x.com. But many platforms — WordPress Gutenberg, Wix, Squarespace, some static site generators — still only recognize the old twitter.com domain for automatic oEmbed resolution.

If you pasted an x.com link expecting it to auto-embed, your CMS may be treating it as a plain URL.

Try this: Replace x.com with twitter.com in your embed URL.

# This might not auto-embed in your CMS:
https://x.com/someuser/status/1234567890

# This usually will:
https://twitter.com/someuser/status/1234567890

Both URLs resolve to the same tweet. X still serves content on the twitter.com domain. The only difference is which domain your CMS recognizes for oEmbed lookup.

If you are using raw embed code (the <blockquote> + <script> approach), the domain inside the blockquote link does not matter as much — the script handles rendering. But if you are relying on your CMS to auto-detect and render the embed from a pasted URL, this distinction matters a lot.


Fix 2: widgets.js Is Failing to Load

Every X embed depends on a single JavaScript file: https://platform.twitter.com/widgets.js. If this script does not load, your embed renders as a plain blockquote — or nothing at all.

Common causes:

  • Ad blockers. uBlock Origin, Brave's built-in blocker, and most privacy-focused browser extensions block platform.twitter.com by default. Your visitors with ad blockers will never see your embeds.
  • Content Security Policy (CSP) headers on your site blocking external scripts.
  • X rate limiting. If your page loads many embeds simultaneously, X can throttle or reject some of the widget requests.
  • Network issues. Corporate firewalls and some ISPs block social media domains.

How to diagnose: Open your browser DevTools (F12), go to the Console tab, and look for errors like:

Refused to load the script 'https://platform.twitter.com/widgets.js'
because it violates the following Content Security Policy directive...

Or in the Network tab, look for a blocked or failed request to platform.twitter.com.

The fix depends on the cause:

If it is your CSP headers blocking the script, add platform.twitter.com to your script-src directive (see Fix 5 below for the full solution). If it is ad blockers, there is no fix — roughly 30-40% of tech-savvy visitors use them, and your embeds will be invisible to those users.

That is not a small number. If your audience is developers, designers, or startup founders, the people most likely to evaluate your product are also the people most likely to never see your X embeds.


Fix 3: Cached or Stale Embed Data

Most content management systems cache oEmbed responses to avoid hitting external APIs on every page load. This is good for performance but means your embed can break and stay broken even after the underlying issue is resolved.

WordPress: WordPress caches oEmbed responses in the wp_postmeta table. To clear it:

DELETE FROM wp_postmeta WHERE meta_key LIKE '_oembed_%';

Or use the simpler approach: edit the post, delete the embed URL, save, re-paste the URL, and save again. WordPress will fetch a fresh oEmbed response.

Webflow and Framer: These platforms cache the embed HTML at publish time. Re-paste the embed code in the editor and republish.

Next.js with ISR: If you are using Incremental Static Regeneration, your pages may be serving a cached version where the embed was fetched hours ago. Trigger a revalidation or set a shorter revalidate interval for pages with dynamic embeds.

Vercel / Netlify: Purge the CDN cache for the specific page. Both platforms have dashboard options or CLI commands for this.

If clearing the cache fixes it temporarily but the embed breaks again within hours, the problem is upstream — move on to the next fixes.


Fix 4: Rate Limiting (429 Errors)

X rate-limits requests to its oEmbed endpoint. If your page embeds 10 or more tweets, some of them will fail on any given page load — especially under traffic spikes.

You will see this in your browser's Network tab as 429 Too Many Requests responses from publish.twitter.com.

Why this happens: Each embed makes its own request to X's servers. Load a page with 15 embeds and you are making 15 near-simultaneous requests from the same origin. X does not like that.

What to do:

  • Reduce the number of individual embeds. If you have 12 testimonials, you do not need 12 separate embed scripts. One carousel with all 12 is a single request.
  • Lazy-load embeds below the fold. Only load the widget script when the embed scrolls into view. This spreads the requests over time.
  • Cache aggressively on your end. If you are fetching oEmbed data server-side, cache the responses for at least 24 hours.

The deeper issue is architectural: X's embed system was designed for "one tweet per article" use cases, not "15 tweets as a testimonial wall." If you are using it for the latter, you are fighting the design.


Fix 5: Content Security Policy Conflicts

If you have set strict CSP headers on your site (and you should for security), X's embed iframes will be blocked unless you explicitly whitelist them.

X embeds need three things allowed in your CSP:

Content-Security-Policy:
  script-src 'self' https://platform.twitter.com;
  frame-src 'self' https://platform.twitter.com https://syndication.twitter.com;
  img-src 'self' https://pbs.twimg.com https://abs.twimg.com;

What each directive does:

  • script-src allows the widgets.js script to load
  • frame-src allows the iframe that X renders the tweet inside
  • img-src allows tweet author avatars and media to display

If you are using a meta tag for CSP instead of headers:

<meta http-equiv="Content-Security-Policy"
  content="script-src 'self' https://platform.twitter.com;
           frame-src 'self' https://platform.twitter.com https://syndication.twitter.com;
           img-src 'self' https://pbs.twimg.com https://abs.twimg.com;">

After adding these, clear your browser cache and reload. CSP violations are cached aggressively by browsers.

The trade-off: Every domain you whitelist in your CSP is a domain that can execute scripts or render content on your page. You are trusting X's infrastructure with your page security. For most sites this is acceptable, but it is worth knowing.


Fix 6: When the Embed Simply Will Not Work

Sometimes there is no fix. The embed is broken for reasons outside your control.

Protected or suspended accounts. If the tweet author made their account private or got suspended, the embed dies. X does not show a helpful error — it just renders nothing. You will not know until a visitor reports it or you manually check.

Deleted tweets. The author deleted the tweet. The embed goes blank. No notification, no fallback content.

X API outages. X's embed infrastructure goes down periodically. When it does, every site using native embeds is affected simultaneously. You cannot do anything except wait.

Regional blocks. Some countries restrict access to X. Visitors from those regions will see broken embeds regardless of your implementation.

What are your options when native embeds fail?

  • Manual HTML cards — You design tweet-like cards with the content hardcoded. Fast, reliable, fully under your control. But visitors cannot click through to verify the original post, which hurts credibility. See how to embed tweets on your website for a comparison of approaches.
  • Screenshots — Worse than manual cards. Unverifiable, blurry on retina displays, and increasingly associated with fake testimonials. Conversion research consistently shows unverifiable testimonials can reduce trust rather than build it.
  • Purpose-built embed tools — Tools like LaunchWall fetch and cache the tweet content server-side, so the embed does not depend on X's widget script loading in your visitor's browser. The content is served from your embed provider's infrastructure, with a link back to the original post for verification. If you are exploring this route, see X embed alternatives for a full breakdown.

The Bigger Picture

If you found this article by Googling "twitter embed not working," you are not alone. This is one of the most searched developer questions in 2026, and there is a reason for that.

X's embed infrastructure has become increasingly unreliable since the Twitter-to-X transition. The oEmbed endpoint gets rate-limited more aggressively. The widget script is blocked by more ad blockers. The documentation is outdated. And there is no indication this trend is reversing.

For a deeper look at why this happened, read why X/Twitter embeds stopped working.

The practical takeaway: if you are embedding one or two tweets in a blog post, native embeds are fine. Fix the issues above and move on.

But if you are relying on X embeds for business-critical social proof — your landing page, your pricing page, your signup flow — you are building on infrastructure that was not designed for your use case and is becoming less reliable over time. Every fix in this guide is a patch. The underlying platform is not optimizing for your success.

For that use case, consider tools that cache tweet content independently of X's embed system, serve it from reliable infrastructure, and give you a single embed code instead of a dozen script tags. That is what LaunchWall does, but there are other options too — see the full comparison of alternatives.


FAQ

Why is my Twitter embed showing a blank box?

The most common cause is widgets.js failing to load. This happens when ad blockers are active, your CSP headers block platform.twitter.com, or X's servers are temporarily down. Open DevTools, check the Console for errors, and check the Network tab for blocked requests to platform.twitter.com. If the script loads fine but the embed is still blank, the tweet may have been deleted or the account may be private.

Do I need the Twitter API to embed tweets?

No. X's native embed code works without API access — it uses a public <blockquote> tag and a JavaScript widget. However, if you want to embed tweets server-side, cache them reliably, or build a testimonial carousel from multiple replies, you will either need API access or a tool that handles it for you. For a walkthrough of the different approaches, see how to add testimonials to your website.

Why do my tweet embeds work locally but not in production?

Three likely causes. First, your production server has stricter CSP headers than your local environment — check your response headers in DevTools. Second, your production CDN is serving a cached version of the page from before you added the embed code — purge the cache. Third, your hosting provider blocks outbound requests to platform.twitter.com at the network level — rare but happens with some corporate hosting setups. Test by loading https://platform.twitter.com/widgets.js directly in a browser on the production domain.

What is the difference between x.com and twitter.com embed URLs?

Both domains point to the same content. X still serves tweets on twitter.com for backward compatibility. The difference matters for CMS auto-embeds: many platforms (WordPress, Wix, Squarespace) recognize twitter.com URLs for automatic oEmbed rendering but do not yet recognize x.com. If you are pasting a raw URL and expecting your CMS to render it as an embed, use the twitter.com version. If you are using the full embed code with the <blockquote> and <script> tags, either domain works.


Stop debugging broken embeds — build a carousel that just works →