Creating an Automated Social Share Card Using Cloudinary and Eleventy

In this post, we'll talk about how to create an automated social share card using Cloudinary. The solution that we'll put together can easily be used for many purposes, but our primary use case will be the creation of a social share card for blog posts.

Social Share Card

Let's first discuss what a social share card is, how it works, what it does and why it's useful.

I'm sure you've seen them in action before - you receive a link from someone via iMessage, or you post something on Twitter, and suddenly, a "miniature image" appears alongside some text - usually containing information about the post.

The process of that image appearing in the first place is often referred to as link unfurling, using an exciting segment of browsers called 'microbrowsers'. There are specific performance implications and best practices applicable to microbrowsers; we will not discuss these in this article, but I highly recommend reading Link Unfurling Engines: Quality, Flavor and Brewing Techniques by Colin Bendell.

Open Graph

Open Graph is an internet protocol created by Facebook, and its purpose is to allow websites to utilise metadata in a standardised way, allowing webpages to represent and expose content as metadata.

Exposing this content means that we can use it. Namely, we can use it for social sharing. Facebook, Twitter, LinkedIn and other sharing mechanisms (including iMessage, WhatsApp etc.) display is based on the metadata found via Open Graph.

Basic Open Graph elements

Open Graph is represented in HTML via <meta> elements, and the four main options are og:title, og:image, og:url and og:description. Here's an example of how this would look like:

<meta property="og:title" content="Title of Article" />
<meta property="og:description" content="Some description" />
<meta property="og:image" content="my-image.jpg" />
<meta property="og:url" content="" />

The above would yield the following result:

Preview the social share card

There are several ways to test how the social share card would look like - Facebook and Twitter both have their debug tools, and there's also Social Share Preview a tool that works with multiple social networks.

Further customisation

Some social networks - Twitter specifically - has additional options that we can implement via twitter:card, which can take multiple values, including summary, summary_large_image and others. The difference between summary and summary_large_image are depicted below.

Summary card

Summary Large Image

It's clear that there are scenarios where the summary card is sufficient; however, the summary large image option also has its use cases. Based on the two screenshots above, it is evident that for my blog, I utilise both of these cards. For the blog, I have a larger, more descriptive card; for every other page, I display the site's logo only since that is sufficient.

Automating social sharing via Cloudinary

We can establish that social sharing cards have value; however, creating them for every blog post would be a rather tedious task. Wouldn't it be amazing to automate this? The good news is that we can create smooth automation using Cloudinary. For this blog post, I will demonstrate 11ty but know that you could use any language/framework to achieve precisely the same.

Create a base image

The first step is to create a base image. In my case, that image looks like the one below.

All you need is an image editor to create the base image - use your imagination and form the image according to your needs; if you don't have access to Photoshop, try Pixlr which is free.

Image size

For best appearance, social sharing cards require specific image dimensions; when writing this article, that should be 1200 x 675 pixels. Ensure that the base image you create is this size or has an aspect ratio of 16:9. (I have used 1200 x 630, which seems to be working just fine as well)

Once you have the base image ready, upload that to Cloudinary and copy its access URL.

Text Layers

Cloudinary supports text overlays, which means that we can add any text as an overlay on top of an existing image. The text overlay uses Google Fonts behind the scenes, which means that any font face available in Google Fonts can be used for the overlay. Furthermore, we can customise the font size, weight and colour.

We can apply the text overlay using the l_ flag in Cluodinary (l for layer) by updating the access URL for the base image:,h_630,c_fit,q_auto,f_auto/w_1000,c_fit,co_rgb:eee,g_west,x_120,y_-60,l_text:Roboto_70_line_spacing_-10_semibold:Hello World this is my blog post title/v1618935929/share-card.png

What's going on in the above URL? Notice that first, we are resizing the entire image to 1200 x 630 pixels, and we apply q_auto and f_auto. These two flags heavily optimise our image.

The next section is w_1000,c_fit,co_rgb:eee,g_west,x_120,y_-60,l_text:Roboto_70_line_spacing_-10_semibold:Hello World this is my blog post title. Notice that this is separated by / in the URL, indicating a new transformation set. The new transformation in our case is equal to a new layer which is 1000 pixels in width, has a position of 120 on the x axis and -60 on the y' axis. The settings are also clear: Roboto, size 70, -10line spacing and the font-weight is semibold, followed by a sample text, and its colour iseee` (grey).

Putting all this together results in the image below.

Open Graph via 11ty

11ty has a great plugin system, and one of the available plugins is metagen - a <meta> element generator.

Setting up the plugin is super easy, just follow the steps outlined in the npm repository. Once the plugin is setup and configured, we can generate social sharing cards with ease:

{% set sanitisedTitle = title | sanitise %}
{% set image = ',h_630,c_fit,q_auto,f_auto/w_1000,c_fit,co_rgb:eee,g_west,x_120,y_-60,l_text:Roboto_70_line_spacing_-10_semibold:' + sanitisedTitle + '/v1618935929/share-card.png' %}
{% metagen
name = name,
title = title + ' by ' + author,
desc = excerpt,
twitter_card_type = "summary_large_image",
url = url + page.url,
twitterHandle = twitter,
img = image

Note the sanitise pipe operation. It's a simple filter added to .eleventy.js to allow special characters to appear in the URL. One example is if the blogpost title contains a /, that would be used as the start of a new transformation in Cloudinary and would break the Cloudinary URL. To make sure that this doesn't happen, we need to use both escape and encodeURLComponent in the sanitise filter:

eleventyConfig.addFilter('sanitise', (value) ==> {
return escape(encodeURIComponent(value));

With all of these settings in place, we now have an automated way that generates social share cards for us using the blog post's title automatically.

A plugin for Eleventy

In light of everything discussed so far, to help you automate this process, I am pleased to announce that I have released a plugin for 11ty that allows the automatic creation of social share cards. Take a look at the repository for options on configuring the plugin to suit your needs. The plugin is responsible for building the final URL, as discussed in this article, and it allows for heavy customisation via changeable parameters.


Social share cards give great value when sharing content via microbrowsers - such as Twitter, Facebook, WhatsApp and others. Manually creating these cards can be a lenghty and tedious task, luckly for us, there are ways to automate the process by using a services such as Cloudinary.