Twitter's embed API has a few things that are less than desireable. Here's an example of the embed code Twitter gives for this tweet.
<!-- I've formatted it here so it is more readable. This is given as a single line from Twitter -->
<blockquote class="twitter-tweet" data-dnt="true">
<p lang="en" dir="ltr">
Tweets embed on my blog are now statically-generated as part of the page and
its images are optimized using Next.js 10’s <Image /> component
<br /><br />
Meaning:<br />
- the tweets are available at page load<br />
- no more cumulative layout shift (page jumping around) caused by loading
embed tweets
<a href="https://t.co/fWCpiNN4Bo">pic.twitter.com/fWCpiNN4Bo</a>
</p>
— Jane Manchun Wong (@wongmjane)
<a
href="https://twitter.com/wongmjane/status/1330273157245243394?ref_src=twsrc%5Etfw"
>November 21, 2020</a
>
</blockquote>
<script
async
src="https://platform.twitter.com/widgets.js"
charset="utf-8"
></script>
As Jane alludes to in the embed code above, with the Twitter embed, the Tweet card isn't available at page load. You could just use the given blockquote
, and that would get you pretty far, but if you wanted a more Twitter like experience you also need to load Twitter's widgets.js script. Which then in turn means cumulative layout shift caused by the script replacing the blockquote
with an iframe
. You can see in the first couple of seconds in Lee Robinson's YouTube video what this looks like. (This video as well as the provided links given in the video description were very helpful for me creating static Tweet cards for my site - it's worth it to watch the whole video if you are interested in doing this as well)
On top of that, loading in the widgets.js script and accompanying iframe is not "free". Including Jane's Tweet using the embed code would have added an additional 1.4MB of resources to the page - which feels like a lot for mostly static content.
So for this site, I decided I wanted to do what a lot of people like Jane and Lee have already been doing and use static Tweet cards.
I took inspiration (and code) from Lee's mentioned YouTube video. But one difference is, Lee is using Next.js where I am currenlty using Remix. So instead of querying for Tweets in getStaticProps
I wanted to be able to just embed the needed data in my MDX file. This would mean stats for the Tweet - replies, retweets, likes - would get stale over time, but I'm fine with that for now. If someone is interested enough they can click on the link and see the updated stats in Twitter.
To make it easier for myself, I created a route in my Remix app which I can pass a Tweet ID and it returns back a formatted JSON object of the Tweet data from the Twitter API. I can then pass this data to the Tweet component created for use in my MDX files.
Here's how I am using it in the MDX file:
<Tweet
{...{
id: "1330273157245243394",
text: "Tweets embed on my blog are now statically-generated as part of the page and its images are optimized using Next.js 10’s <Image /> component\n\nMeaning:\n- the tweets are available at page load\n- no more cumulative layout shift (page jumping around) caused by loading embed tweets https://t.co/fWCpiNN4Bo",
author_id: "337119125",
public_metrics: {
retweet_count: 22,
reply_count: 16,
like_count: 494,
quote_count: 7,
},
created_at: "2020-11-21T22:13:30.000Z",
attachments: { media_keys: ["3_1330270041997271041"] },
media: [
{
width: 1636,
media_key: "3_1330270041997271041",
height: 1800,
type: "photo",
url: "https://pbs.twimg.com/media/EnYRjhyXYAEclVi.jpg",
},
],
author: {
name: "Jane Manchun Wong",
url: "https://t.co/q7v0DjHk9o",
profile_image_url:
"https://pbs.twimg.com/profile_images/1499012482975014912/lp2juUP3_normal.jpg",
id: "337119125",
protected: false,
verified: true,
username: "wongmjane",
},
}}
/>
I might change this up in the future and have the Tweet component retrieve the latest stats after the initial render. But like I said, I'm fine with the stats getting stale over time for now. It doesn't really take away from the main point of the Tweet card and is extra complexity I don't want to worry about at the moment.
So to recap...
Here's an example of using just the blockquote
from the Twitter embed code:
Tweets embed on my blog are now statically-generated as part of the page and its images are optimized using Next.js 10’s <Image /> component
— Jane Manchun Wong (@wongmjane) November 21, 2020
Meaning:
- the tweets are available at page load
- no more cumulative layout shift (page jumping around) caused by loading embed tweets pic.twitter.com/fWCpiNN4Bo
And here's an example of using the static Tweet card:
I think the static Tweet card looks much nicer. Plus, if you checkout the developer console, the resources loaded for this page are probably less than 1.4MB altogether, so that's nice too.