Inspired by Jason Lengstorf, I added social sharing images to all my blog posts on stevenhicks.me. This means that when you share an article from my site to a place like Twitter, you'll get a nice big card like this:
Sweet! I can't get enough of those 70s shag carpet vibes.
Prior art
Before I show you how I hooked this up to my eleventy site, consider this article by Stephanie Eckles about using puppeteer to generate social share images. If you want to use HTML & CSS to create your social sharing images, that is probably what you're looking for!
The method I chose(1) uses Cloudinary to overlay the article title onto a common social sharing image.
Most of what I needed was covered by Jason in his articles on adding text overlays in Cloudinary, designing a social sharing card, and auto-generating social share images with get-share-image
. Thanks, Jason!
Heads up that the most time-consuming part was tweaking the Cloudinary text overlays. Lots of fiddling with cryptic arguments. It's literally pushing pixels to get text in the right place.
Emitting the image URLs in eleventy
Here's my addition to this problem space: a PR that shows everything I needed to do to hook up the images in eleventy!
There's not a lot there, but let's walk through it.
1. Add the get-share-image
dependency
You'll do this with npm install @jlengstorf/get-share-image
or yarn add @jlengstorf/get-share-image
. I added it to my devDependencies
because I care about separating dev dependencies from runtime dependencies. Maybe you don't care β I'm not going to arm-wrestle you over it.
2. Add an eleventy computed data file
Eleventy's computed data files inject computed properties into a page template for each page they apply to. Like maybe you want to compute a social sharing image URL that's based on the article title!
I added a file named blog.11tydata.js
to the blog/
folder. I chose to put it in the blog/
folder because I only wanted to generate social images for my blog articles; it seemed silly to me to generate a social image for my about page that said "About". I'm not sure if the file name needs to start with blog
, but that's what the docs did in their example (posts/posts.11tydata.js
), so I just went with it.
The contents of blog/blog.11tydata.js
:
const getShareImage = require('@jlengstorf/get-share-image').default;
module.exports = {
eleventyComputed: {
shareImage: (data) => {
return getShareImage({
// settings for cloudinary overlays
});
},
},
};
- We pull in the
get-share-image
dependency. - We export an object with a property named
eleventyComputed
. - Each property of
eleventyComputed
is a computed property that becomes available in your page templates. In our case, we compute a property namedshareImage
. The value of it is the result of a call togetShareImage
with a bunch of configuration for the Cloudinary overlay.
This shareImage
property gets computed for each page within blog/
, based on its metadata (that's what the data
argument passed into the function represents).
The only dynamic data here for my site was the title
property that gets passed to getShareImage
:
module.exports = {
eleventyComputed: {
shareImage: (data) => {
return getShareImage({
// ...
title: data.title,
// ...
});
},
},
};
3. Emit the shareImage
property in your template
I have one base page template for my site. It's based on the pug language.
I updated it to emit a shareImage
in the appropriate meta tags if it exists:
meta(property='og:image' content=`${shareImage || 'https://www.stevenhicks.me/static/img/avatar.jpg'}`)
meta(property='twitter:image' content=`${shareImage || 'https://www.stevenhicks.me/static/img/avatar.jpg'}`)
All blog articles will have that shareImage
computed property, so they'll emit their generated images. Pages like Home and About won't have a shareImage
computed because I put the blog.11tydata.js
file in the blog/
folder β so they'll get stuck with an image of my face. MY FACE!
Wrap it up, Steve
The PR ends up being 39 lines added β and over half of that is configuration settings for the text overlay. JavaScript is neat!
You likely found this article because you've already got an eleventy site, but if you don't, you should absolutely give it a look. It's a great option for building a blog or any other site where the data doesn't change frequently. I find it more intuitive than other popular options. This example especially demonstrates how well it's designed for generating dynamic content. Every time I come across a new problem I'm delighted to find there's a simple mechanism built into eleventy to solve it.
1 Hahahahaha I act like I had agency in this decision but really I didn't see Stephanie's article until I had invested a lot of time in generating an image template based on Jason's articles. I'm as much a sucker for the sunk-cost fallacy as anyone, and here we are.
Top comments (0)