Dynamically generated social media images for use in Eleventy sites.

Usage no npm install needed!

<script type="module">
  import 11tyrocksEleventyPluginSocialImages from 'https://cdn.skypack.dev/@11tyrocks/eleventy-plugin-social-images';


Eleventy Plugin: Social Images

Dynamically generated social media images.

This package creates dynamic images sized for social media tags (particularly Twitter and Facebook) based on your available pages. Use one of the predefined color themes, or define your own style, template, or both to customize the layout.

Configure the CLI script to run after your Eleventy build, and by default images will be created in _site/previews/ as png images. Use the CLI options to define a custom outputDir and/or a custom imageDir.

The images are only created in your output directory since the process runs after the Eleventy build is complete.

The window size used for the screenshot is 600px wide by 315px tall (which is then saved at 2x resolution) which you can use to test your template and styles if you choose to create them custom.

🧪 If you find a problem please add an issue. This has been tested on local builds and within Netlify, but needs broader tests by the community. Thanks to the contributors!


First, install the package:

npm install @11tyrocks/eleventy-plugin-social-images

There are three steps to using this package:

  1. Setup the command line script and add it to your Eleventy build
  2. Generate a JSON file containing data for each page you want social images
  3. Include a reference to the image in your templates

If you're using a host with continuous integration (like Netlify) you will also need to amend the build script you provide to your host to add the following and ensure Chrome headless is successfully launched for use by Puppeteer in the pipeline:

AWS_LAMBDA_FUNCTION_NAME=trickpuppeteer npm run build

Setup the CLI Script

Technically, this package offers a plugin component, but most of the functionality is added by calling the command line script.

The minimum setup for the cli script is:

eleventy-social-images --siteName 'Your Site Name'

It's recommended to add this after building Eleventy for production to reduce strain on your system when in serve mode, for example by adding the following in your package.json:

"scripts": {
  "social-images": "eleventy-social-images --siteName 'Your Site Name'",
  "start": "eleventy --serve",
  "build": "eleventy ; npm run social-images"

Setup the Page Data JSON

The Eleventy plugin itself is only providing an optional filter to help format titles within the required JSON file.

The filter is called addNbsp and it inserts a non-breaking space - nbsp; - between the last two words in the title to prevent a single word dangling on the last line (called an "orphan" by typographers).

See the next section for how to add the plugin.

To create the required page data JSON, here is a starting template that loops through the all collection and includes the two expected keys: title and imgName.

Important: Be sure to add the full path of your pages.json file to either .gitignore or .eleventyignore to prevent an infinite loop when Eleventy is in --serve mode.

  • This should be created as a Nunjucks template, ex. pagesjson.njk so that it is recognized by Eleventy for processing.
  • Place this either at the root of your input directory, or in a custom directory in your input folder (ex. _generate).
  • Note the unique frontmatter, which essentially mean "do not include this in the normal site output".
  • If you have customized your input directory via your Eleventy config, you may want to change the permalink value because it is relative to your project root, not the directory where it is placed.
  • The example uses the addNbsp filter which is optional - see the next section for how to include the plugin and gain access to that filter.
  • When the addNbsp filter is used, you must also include safe to allow the nbsp; to be successfully included.
  • slug is a built-in Eleventy filter that will for example transform 'Hello World' into 'hello-world'
permalink: "./pages.json"
permalinkBypassOutputDir: true
eleventyExcludeFromCollections: true
{%- for pages in collections.all %}
      "title":"{{ pages.data.title | addNbsp | safe }}",
      "imgName":"{{ pages.data.title | slug }}"
  }{% if loop.last == false %},{% endif -%}
{% endfor %}

You may modify what is used as the values based on your own naming convention and permalink structure. You may need to scope it to a particular collection vs. all. Check out the 11ty docs on collections >

Custom template variables

Added in v0.3.0 - include additional variables to pass into a custom template, such as:

{%- for pages in collections.all %}
      "title":"{{ pages.data.title | addNbsp | safe }}",
      "imgName":"{{ pages.data.title | slug }}",
      "variables": {
        "postdate": "{{ pages.data.postdate }}"
        {%- if pages.data.description %},
        "description": "{{ pages.data.description }}"
        {% endif %}
  }{% if loop.last == false %},{% endif -%}
{% endfor %}

Use in your template by adding data attributes to elements that should contain the variable value. For example <p data-postdate></p> where you want the postdate to appear.

Unavailable variables will simply produce empty elements. If you find the empty elements are impacting your template styles, remove them via CSS with the :empty selector, ex p:empty { display: none }.

Kudos to Thomas Michael Semmler for initiating the variables functionality!

Optional: Add the Plugin

As noted previously, the plugin enables the addNbsp filter.

Install the plugin in your 11ty project:

Then, include it in your .eleventy.js config file:

const socialImages = require("@11tyrocks/eleventy-plugin-social-images");

module.exports = (eleventyConfig) => {

Add image references in your templates

The final step is up to you, which is placing the social media tags for you preferred services in the <head> of your Eleventy templates.

Here are Nunjuck examples of including the image for both Twitter and Facebook - both of which require additional tags for full social share functionality. Check out my 11ty Netlify Starter for full tags for these services.

{%- set pageSocialImg %}{{ meta.url }}/previews/{{ title | slug }}.png{% endset
<meta property="og:image" content="{{pageSocialImg}}" />
<meta name="twitter:image" content="{{pageSocialImg}}" />

Note that the compiled image URL needs to be a full, absolute URL in order to work correctly for the social services. In this example, taken from my 11ty Netlify Jumpstart, meta.url is defined in _data/meta.js, such as:

module.exports = {
  url: process.env.URL || "http://localhost:8080",

Where the env.URL is provided by Netlify at build time. Your host may offer a similar option, or you may choose to hardcode your live URL into the tag.

CLI Config Options

Option Type Default
siteName string 11ty Rocks!
outputDir string _site
imageDir string previews
dataFile string pages.json
templatePath string
stylesPath string
theme enum: 'blue' | 'green' | 'minimal' | 'sunset' | 'pop' blue
width number 600
height number 315
deviceScaleFactor number 2

Config Examples

The defaults are setup to assume Eleventy build defaults. So, the images will be created in _site/previews/ as png images, and expect your pages.json to live at the project root.

Custom output directory

If you have set a custom output directory, then also update outputDir, ex: --outputDir public.

Define theme to use

Preview the predefined themes >

To select, from one of the predefined themes, pass --theme [themename] where themename is one of the following:

  • blue (default)
  • green
  • minimal
  • sunset
  • pop

Custom image dimensions

By default, this plugin will create social images that are 600px wide and 315px tall. To choose different dimensions, pass --width and --height arguments, as in --width 1280 --height 720.

The default device scale factor (or device pixel ratio) is 2, emulating high-dots-per-inch/Retina displays. To change the device scale factor, you can pass ---deviceScaleFactor, as in --deviceScaleFactor 1.

Custom preview directory to output images

To define another name for your images to live, pass the directory name without the output path, ex: --imageDir img.

Reminder: The images are only created in your output directory since the process runs after the Eleventy build is complete.

Custom style

To use your own stylesheet, create a CSS file anywhere in your project. Then, pass the path like --stylesPath social/style.css.

Your stylesheet will then be used instead of the default one.

Note on web fonts: For best results ensuring the web font loads for the screenshot, use the CSS @import option within your stylesheet.

Custom template

To use your own template, create an html file in your project. You may want to exclude it from Eleventy to prevent it being built as a page by adding it to .eleventyignore or placing it outside of your customized input directory.

Then, pass the path like --templatePath social/template.html.

Your template will then be used instead of the default one.

Refer back to custom template variables for how to enable additional template data.

Important notes on custom templates

You must include an h1 to be used as the hook to replace the title of the content. The rest of the template is up to you!

Include the following so that the stylesheet can be injected into the template:

  {{ style }}

If you are not customizing the entire stylesheet but would like to alter part of it, such as the h1 size, you can add that singular style after {{ style }} to override the defaults thanks to the CSS cascade.

To use a custom template but keep using a predefined theme, add a class value on <body> with your preferred theme value.

Custom template and style

You can pass both a custom template and stylesheet by defining both CLI options, ex. --templatePath social/template.html --stylesPath social/style.css.

Fully customized example

Since this full example includes style, the only option missing is theme since it would have no additional effect.

eleventy-social-images --siteName 'My Cool Site' --outputDir public --dataFile src/_generate/pages.json --imageDir imgs --templatePath social/template.html --stylesPath social/style.css --width 1280 --height 720 --deviceScaleFactor 1


If you use WSL, you'll need a browser. Install chrome in WSL by doing:

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt -y install ./google-chrome-stable_current_amd64.deb

You can confirm this worked by doing google-chrome --version.


Hi - I'm Stephanie Eckles (@5t3ph), creator of 11ty.Rocks and the other resources compiled there.

If you enjoy my work and use my projects, please consider buying me a coffee.

This plugin is an adaptation for my solution originally detailed in this blog post and included in my 11ty Netlify Jumpstart. It's in active use on my 11ty-based sites:


The included gradient themes inspired by uiGradients