Twitter Cards on Jekyll
- Personalizing GitHub Pages
- Jekyll on Win10
- Twitter Cards on Jekyll
You have a Jekyll blog (most likely GitHub Pages), and you wrote an awesome post! Once it’s published, it’s time to tweet the link, lay in the hammock, and watch the visitors roll in.
…oh. That won’t do. You can barely tell I shared a link! Nobody scrolling by is going to stop for that.
Ah, there we go. That’s the good stuff.
This post covers how I added support for “Twitter Cards” to my Jekyll blog, even though my theme didn’t have anything pre-built for me.
Table of Contents:
- tl;dr (Too long; didn’t read)
- Figure out the basics
- Google around for examples
- Ctrl + V like a boss
- Tweak to fit your needs
- Use the Validator Tool
- Adding Slack support
- Summary
tl;dr (Too long; didn’t read)
- Paste code into
/_includes/head.html
- Ensure it refers to variables that exist:
- “site.name” variables are in your top-level
_config.yml
file - “page.name” variables are in your individual blog post’s YAML front matter
- “site.name” variables are in your top-level
- Tweak as desired
- Refer to the Twitter Cards documentation when you get stuck
- Use the Validator Tool before you tweet!
Figure out the basics
I’ll skip the part where I didn’t know the proper name, and was Googling things like why doesn't stupid twitter preview my stupid links
. But step one is always to figure out the silly marketing name of the thing you’re trying to do. (Slack calls their link previews “unfurling.”)
Twitter Cards documentation demonstrates the different card types available. I’m not doing any video right now, so I’m looking at two card types:
Looking through both types’ properties, you’ll notice that the required properties are the same (card, title, description). Quite handy.
Google around for examples
Armed with the proper term, now I can send Google queries like twitter cards jekyll
. Two useful hits that I stole borrowed from:
- Defining Twitter Cards in your Jekyll Template [alligator.io]
- Supporting Twitter Cards with Jekyll [davidensinger.com]
Both links show the final code used, which proved helpful to pick and choose from. But only the first link says where to put the code: the “head.html include file”, which was \_includes\head.html
for my site. Bingo.
Ctrl + V like a boss
This is what my head.html file looked like: Old head.html
Paste your new code in there, basically anywhere. I decided to just paste in the code block from the first site into the very bottom of the file (right before </head>
). However, VS Code’s syntax highlighting parses that line 26 oddly, so I ended up inserting the new code at line 26 and bumping the last “paragraph” down. Whatever works.
But there’s some basic stuff in our paste job that we need to fix. So…
Tweak to fit your needs
I’ll start with the final code I used, and then break down why I did each section that way, so you can make similar considerations when you tweak.
<!-- Twitter cards -->
<meta name="twitter:site" content="@{{ site.twitter_username }}">
<meta name="twitter:creator" content="@{{ page.author }}">
<meta name="twitter:title" content="{{ page.title }}">
{% if page.summary %}
<meta name="twitter:description" content="{{ page.summary }}">
{% else %}
<meta name="twitter:description" content="{{ site.description }}">
{% endif %}
{% if page.image %}
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="{{ site.url }}{{ page.image }}">
{% else %}
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="{{ site.title_image }}">
{% endif %}
<!-- end of Twitter cards -->
Variables
Variable syntax is {{ variablename }}
. In Jekyll’s case, you’ll have {{ site.variablename }}
and {{ page.variablename }}
.
- Site variables are defined in your site’s
_config.yml
file- For example, my site’s _config.yml specifies a “title_image”, which I can refer to with
{{ site.title_image }}
- For example, my site’s _config.yml specifies a “title_image”, which I can refer to with
- Page variables are defined in each post’s YAML front matter
- An example post shows the variables (title, summary, author, etc.) at the very top. Therefore,
{{ page.title }}
will grab the post’s title
- An example post shows the variables (title, summary, author, etc.) at the very top. Therefore,
Site, Creator, Title
twitter:site
- I already had a Twitter username defined in my site’s config, so I’m just referencing it here to reduce hard-coded values.
twitter:creator
- Not required, but interesting to add in case I have a guest author. I can easily refer to a different “author” at the top of the post.
Twitter’s looking for a Twitter handle in “@username” format here, so I added “@” to the front of both strings.
twitter:title
- The individual post’s title. Hopefully pretty self-explanatory. :)
Description
twitter:description
- The sub-headline. I found that the theme I adopted was using “summary” instead of “description” for this, but either way is easy enough to solve for.
<!-- Did I include a "summary" variable in this post's front matter? -->
{% if page.summary %}
<!-- I did! Use it -->
<meta name="twitter:description" content="{{ page.summary }}">
{% else %}
<!-- Nope! Use the "description" defined in the site's _config.yml instead -->
<meta name="twitter:description" content="{{ site.description }}">
{% endif %}
Image, Card
Here’s where I got a little fancy. I don’t always include an image in every post, so I decided to leverage a simple if/else to check for an image on the post, and only use the Large Image type when there’s something useful to display.
<!-- Did I include an "image" variable in this post's front matter? -->
{% if page.image %}
<!-- I did! Select the "large image" card type, and supply the image path -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="{{ site.url }}{{ page.image }}">
{% else %}
<!-- Nope! Select the "summary" card type, supplying the site's title image -->
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="{{ site.title_image }}">
{% endif %}
Note that none of my posts had an “image” property defined! I’m adding it selectively to new posts from here on out. Therefore, it’s just as easy for you to create whatever you want to help support your goal.
You could easily just define a full image path in each post, instead of copying my site.url + page.image
string concatenation.
Use the Validator Tool
Finished adding your changes? Twitter helpfully provides a Validator Tool to figure out whether your cards are working before tweeting 20 times.
Adding Slack support
Just kidding! Slack surprised me by totally cooperating with “unfurling” activities after I added Twitter meta tags. Thanks, Slack!
Summary
No link previews = bad. Link previews = excellent.
If you’re here, I hope that means you were successful, and you learned a little about Jekyll’s inner workings along the way. Reach out if you have suggestions or questions!