Update: Rendering Static Tweets
A few weeks ago, I wrote a post about rendering static tweets. I’ve made a few important improvements, worthy enough of a new post.
In my original post, I described using a proxy to inject Twitter API headers. This is hacky, and leads to flaky builds, because the build server needs to handle a NodeJS proxy running in the background1. I got this working on Vercel and Cloudflare Pages2, but there was no guarantee the build would pass, and I was constantly re-running failed builds. Neither fun nor productive. In the past few weeks I’ve wanted to remove this functionality from my blog because it’s made it more difficult to preview and deploy.
Last week I was reading Nicholas Whittaker’s blog, specifically a post he wrote about static embeds for tweets and videos (sounds familiar, right?). He’s using workers to handle some of the proxying, but notably, he’s not calling Twitter’s private API, which requires authentication, he’s calling a public one.
I had no idea https://cdn.syndication.twimg.com/
existed. It’s a completely open API you can use for fetching tweets, which means it’s perfect for static sites!
Try it out: curl "https://cdn.syndication.twimg.com/tweet?id=1406108535356678145"
Check out the updated shortcode here.
After some further sleuthing on Nicholas’ blog, I realised you can configure caches in Hugo. This means you can cache calls to getJson
, and push the cache to git. If a tweet ever gets deleted, as long as it exists in the cache3, I can continue rendering the tweet. Neat!
This sounds more complicated than it is. The Hugo shortcode makes a request to
localhost:8080/{tweetId}?auth={authToken}
, the proxy then callshttps://api.twitter.com/1.1/statuses/show?id=${tweetId}
with the same tweet ID and an authentication header. The proxy is on GitHub if you want to take a peek. ↩︎Here is what the build command looked like:
cd twitter-proxy && npm install && node index.js & sleep 5 && echo "Done" && hugo -t hello-friend --baseUrl=$BASE_URL --ignoreCache
↩︎Provided you’ve set
maxAge: -1
, so the cache is never purged. My config is here. ↩︎
On the web
Blaugust 2025
Fri Aug 1 2025 by joelchrono's website📝 1 August 2025 at 13:56 - Trying …...
Fri Aug 1 2025 by Kev QuirkMounting The Atmosphere
Thu Jul 31 2025 by oppiliappan's μblogMaybe the Fastest Disk Usage Program on macOS
Thu Jul 31 2025 by Andrew Healey's BlogPets have names, livestock is tagged
Sat Jul 12 2025 by nicholas.cloud
Generated by openring