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
Building a macOS app to know when my Mac is thermal throttling
Sat Dec 27 2025 by Stan's blogBusy work and family visits - W51
Wed Dec 24 2025 by joelchrono's blogA Fair, Cancelable Semaphore in Go
Sun Dec 21 2025 by Andrew Healey's BlogIs Firefox Firefucked?
Fri Dec 19 2025 by Kev QuirkAn average new Dad's approach to training with kettlebells (and other tools) to develop General Physical Preparedness (GPP) at home
Mon Nov 24 2025 by Nicholas A. Danes, PhD
Generated by openring