Auto-Generated Social Media Images

Avatar of Chris Coyier
Chris Coyier on (Updated on )

Grow sales with a smart marketing platform. Try Mailchimp today.

Mailchimp tracking pixel

I’ve been thinking about social media images again. You know, the images that (can) show up when you share a link in places like Twitter, Facebook, or iMessage. You’re essentially leaving money on the table without them, because they turn a regular post with a little ol’ link in it into a post with a big honkin’ attention grabbin’ image on it, with a massive clickable area. Of any image on a website, the social media image might be the #1 most viewed, most remembered, most network-requested image on the site.

It’s essentially this bit of HTML that makes them happen:

<meta property="og:image" content="/images/social-media-image.jpg" />

But make sure to read up on it as there are a bunch other other HTML tags to get right.

I think I’m thinking about it again because GitHub seems to have new social media cards. These are new, right?

Those GitHub social media images are clearly programmatically generated. Check out an example URL.

Automation

While I think you can get a lot of bang out of a totally hand-crafted bespoke-designed social media image, that’s not practical for sites with lots of pages: blogs, eCommerce… you know what I mean. The trick for sites like that is to automate their creation via templating somehow. I’ve mentioned other people’s takes on this in the past, but let’s recap:

You know what all those have in common? Puppeteer.

Puppeteer is a way to spin up and control a headless copy of Chrome. It has this incredibly useful feature of being able to take a screenshot of the browser window: await page.screenshot({path: 'screenshot.png'});. That’s how our coding fonts website does the screenshots. The screenshotting idea is what gets people’s minds going. Why not design a social media template in HTML and CSS, then ask Puppeteer to screenshot it, and use that as the social media image?

I love this idea, but it means having access to a Node server (Puppeteer runs on Node) that is either running all the time, or that you can hit as a serverless function. So it’s no wonder that this idea has resonated with the Jamstack crowd who are already used to doing things like running build processes and leveraging serverless functions.

I think the idea of “hosting” the serverless function at a URL — and passing it the dynamic values of what to include in the screenshot via URL parameter is also clever.

The SVG route

I kinda dig the idea of using SVG as the thing that you template for social media images, partially because it has such fixed coordinates to design inside of, which matches my mental model of making the exact dimensions you need to design social media images. I like how SVG is so composable.

George Francis blogged “Create Your Own Generative SVG Social Images” which is a wonderful example of all this coming together nicely, with a touch of randomization and whimsy. I like the contenteditable trick as well, making it a useful tool for one-off screenshotting.

I’ve dabbled in dynamic SVG creation as well: check out this conference page on our Conferences site.

Unfortunately, SVG isn’t a supported image format for social media images. Here’s Twitter specifically:

URL of image to use in the card. Images must be less than 5MB in size. JPG, PNG, WEBP and GIF formats are supported. Only the first frame of an animated GIF will be used. SVG is not supported.

Twitter docs

Still, composing/templating in SVG can be cool. You convert it to another format for final usage. Once you have an SVG, the conversion from SVG to PNG is almost trivially easy. In my case, I used svg2png and a very tiny Gulp task that runs during the build process.

What about WordPress?

I don’t have a build process for my WordPress site — at least not one that runs every time I publish or update a post. But WordPress would benefit the most (in my world) from dynamic social media images.

It’s not that I don’t have them now. Jetpack goes a long way in making this work nicely. It makes the “featured image” of the post the social media image, allows me to preview it, and auto-posts to social networks. Here’s a video I did on that. That’s gonna get me to a place where the featured images are attached and showing nicely.

But it doesn’t automate their creation. Sometimes a bespoke graphic alone is the way to go (the one above might be a good example of that), but perhaps more often a nicely templated card is the way to go.

Fortunately I caught wind of Social Image Generator for WordPress from Daniel Post. Look how fancy:

This is exactly what WordPress needs!

Daniel himself helped me create a custom template just for CSS-Tricks. I had big dreams of having a bunch of templates to choose from that incorporate the title, author, chosen quotes, featured images, and other things. So far, we’ve settled on just two, a template with the title and author, and a template with a featured image, title, and author. The images are created from that metadata on the fly:

So meta.

This ain’t Puppeteer. This ain’t even the PhantomJS powered svgtopng. This is PHP generated images! And not even ImageMagick, but straight up GD, the thing built right into PHP. So these images are not created in any kind of syntax that would likely feel comfortable to a front-end developer. You’re probably better off using one of the templates, but if you wanna see how my custom one was coded (by Daniel), lemme know and I can post the code somewhere public.

Pretty cool result, right?

Tweet

I get why it had to be built this way: it’s using technology that will work literally anywhere WordPress can run. That’s very much in the WordPress spirit. But it does make me wish creating the templates could be done in a more modern way. Like wouldn’t it be cool if the template for your social media images was just like social-image.php at the root of the theme like any other template file? And you template and design that page with all the normal WordPress APIs? Like an ACF Block almost? And it gets screenshot and used? I’ll answer for you: Yes, that would be cool.