npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

eleventy-plugin-social-img

v1.3.3

Published

A plugin for generating social share images at build time. Returns a URL for the image to be used in Twitter & Open Graph meta tags.

Downloads

33

Readme

eleventy-plugin-social-img

An Eleventy plugin for generating social share images at build-time. It uses capture-website behind the scenes to capture a screenshot of the given input and save it to a given output file path. The URL for that generated image will be returned by the shortcode to be used in <meta> tags for Twitter and Open Graph. This plugin can be paired with eleventy-plugin-metagen for complete social share functionality.

The default viewport size for taking a screenshot is 600px by 315px. To use a custom width and height, utilize the width and height arguments. If you want a higher resolution display, set highRes equal to true for a 1200px by 630px image size (double the default dimensions).

Installation

In your Eleventy project, install the plugin from npm:

npm install eleventy-plugin-social-img

Then add it to your Eleventy Config file:

const socialImg = require('eleventy-plugin-social-img');

module.exports = (eleventyConfig) => {
    eleventyConfig.addPlugin(socialImg);
};

What does it do?

The plugin turns 11ty shortcodes like this:

{% set imgUrl %}
    {% socialImg
        theme=2,
        title="Some Interesting Blog Post Title Text",
        inputDir="./src",
        fileName="my-img",
        outputPath="/social-share/",
        themeColor="#7968c6",
        fontColor="#000215"
    %}
{% endset %}

into images like this:

theme-two-demo

The shortcode returns a URL for the generated image which can be used in document metadata for og:image and twitter:image meta tags. I recommend storing the output of socialImg in a template variable like demonstrated with {% set imgUrl %}.

<!-- Twitter and Open Graph -->
<meta name="og:image" content="{{ imgUrl | trim }}">
<meta name="twitter:image" content="{{ imgUrl | trim }}">

The inputDir argument is required. If the path created from inputDir concatenated with outputPath doesn't exist, the paths in will be created. The image will be generated and placed at the end of ${inputDir}${outputPath} with the extension in type (default 'png'). If the given filepath and image already exists, the shortcode will generate a new image and overwrite the old one.

Handling URLs

With the process.env.URL environment variable provided by Netlify, the image URL generated by the socialImg shortcode can be prefixed with the live sites URL. The return statement of your Eleventy config file will determine which directory of templates get transformed to HTML (e.g. input) and the directory to output the static files (output). The input directory in your Eleventy config file should be the same value you pass the inputDir argument.

Specify an outputPath that is relative to the inputDir directory.

{% socialImg 
    input="<h1>Hello, 11ty!</h1>",
    inputType="html",
    fileName="my-file",
    inputDir="./src",
    outputPath="/social-share/",
    styles=["h1 { color: #f06; }"]
%}

Make sure to use addPassthroughCopy() to include the directory of social share images in your build output. This will ensure that the directory of generated images are included in the sites static output (ie _site) when built and deployed with Netlify.

For the image URLs to be acessed by social card validators, don't forget to tell Eleventy to copy the directory of generated image files specified in inputDir + outputPath into the site output with addPassthroughCopy(). This will make sure that URLs generated by the shortcode like https://some-site.netlify.app/outputPath/fileName work as expected since the static assets will be available at the expected URL.

module.exports = (eleventyConfig) => {

    // Include the directory of generated images from `outputPath` in site output
    eleventyConfig.addPassthroughCopy("./src/social-share/");

    return {
        dir: {
            input: "src",
            output: "_site"
        }
    }
}

If you have the above dir object as shown above, the following shortcode:

{% set imgUrl %}
    {% socialImg
        input="<h1>Hello World!</h1>",
        inputType="html",
        fileName="my-file",
        inputDir="./src",
        outputPath="/social-share/some-dir/",
        styles=[
            "body { background: lightblue; }",
            "h1 { color: #f06 }"
        ]
    %}
{% endset %}

<meta name="og:image" content="{{ imgUrl | trim }}">
<meta name="twitter:image" content="{{ imgUrl | trim }}">

will create the directories /social-share/some-dir/ if they don't already exist, generate the image and return a URL:

https://site-name.netlify.app/social-share/some-dir/my-file.png

If you have a custom domain name through Netlify, then process.env.URL will replace "site-name.netlify.app" with your custom domain.

Usage Options

For a single input (ie a URL or HTML), the shortcode will generate only one image to the specified inputDir + outputPath.

When multiple screenshots are being taken at once with captureWebsite, chrome processes are being launched in parellel and every instance adds a listener to each processes "exit" event to cleanup. The default maximum number of listeners is 10 which can be verified by process.getMaxListeners().

If you have a layout with more than 10 templates feeding into it, then normally with Puppeteer an error would be thrown MaxListenersExceededWarning. I've circumvented this issue by setting a generous MaxListeners ceiling, but a future fix would be to concurrently handle promises returned from the captureWebsite utility. It returns Promise<void>, therefore for 'X' values passed to input or for 'X' pages built using shortcode, the same number of promises will be returned.

When running the project locally, use overwrite=false to make sure captureWebsite isn't running in the background as its performance intensive if you have many socialImg invocations. When building, overwrite=true is safe.

Below are a few options of shortcode usage:

Create an inline object by passing the name=value pair arguments to shortcode:

{% socialImg 
    theme=1,
    title="Some Interesting Blog Post Title",
    img="https://tannerdolby.com/images/headshot3.png",
    initials="TD",
    fileName="my-image",
    inputDir="./src",
    outputPath="/images/",
    themeColor="#102647",
    fontColor="#edefbd"
%}

Define template variables in front matter and pass them to the shortcode:

---
title: Some post about cool stuff
input: "<h1>Hello, world</h1>"
inputType: html
fileName: image-three
inputDir: ./src
outputPath: /share/
styles:
 - "body { background: #f06; }"
 - "h1 { color: #fff; }"
---

 {% socialImg
    input=input,
    inputType=inputType,
    fileName=fileName,
    inputDir=inputDir,
    outputPath=outputPath,
    styles=styles
%}

Pass a single object to the shortcode for a one liner:

---
data:
  theme: 2
  title: Some Post Title
  inputDir: ./src
  outputPath: /share/
---

{% socialImg data %}

To use your own custom templates and styles, have a look at using custom templates. This provides room for creativity because you have a blank canvas and can provide it with any custom content or styles that you want.

Shortcode Options

If a fileName is not present and title is, then the generated image filename will be the value of title slugified. If the outputPath is not present but a fileName or title is, then the default output directory will be ./social-images/. The fileName has higher precendence in the shortcode arguments so if you use both a fileName and title (which is common) then the fileName will be the generated image filename.

Note: the order of shortcode arguments doesn't matter.

| Argument | Type | Desc | |----------|------|------| | inputDir | string | The input directory in your .eleventy.js config file. (Default: ".")| | input | string | The URL, file URL, data URL, local file path to the website, or HTML. (Default: 'url')| | inputType | string | Type of input location for capture-website. Can be a URL or HTML. (Default: 'url')| | outputPath | string | The output file path for generated screenshots. Relative to the value provided in inputDir. | | fileName | string | Name of the generated social share image. | | styles | string[] | The styling for input. Accepts an array of inline code, absolute URLs, and local file paths (must have a .css extension). | | title | string | The page title for images using a theme. | | width | number | Page width. | | height | number| Page height. | | img | string | The URL, file URL, or local file path to a headshot image for theme 1. | | initials | string | The site authors initials. | | highRes | boolean | Sets page width and height to 1200px by 630px. | | theme | number | A number indicating which theme to use (1 or 2). | | themeColor | string | The background color for theme. Any valid CSS background values. | | fontColor | string | The font color for text in themes. | | debugOutput | boolean | Logs the config object to console. |

See capture-website for more details on available arguments. Many config options exist in capture-website and all of them are supported for usage with socialImg.

Using Themes

Two social share image themes exist in this plugin. They use predefined HTML and styles, but the styles can be manipulated with optional arguments and/or the styles argument. When using a theme, make sure to include theme and assign it a value. Do not use input with predefined themes, it will throw an error as the input source (eg HTML) is already supplied to captureWebsite for taking the screenshot.

You can view the predefined themes to preview what generated social share images will look like.

Theme one

Specify a theme, title, img, initials, fileName, inputDir, and outputPath.

{% set imageUrl %}
    {% socialImg
        theme=1,
        title="Some Interesting Blog Post Title Text",
        img="https://tannerdolby.com/images/headshot3.png",
        initials="TD",
        fileName="theme-one",
        inputDir="./src",
        outputPath="/social-share/"
    %}
{% endset %} 

Theme two

Specify a theme, title, fileName, inputDir, and outputPath.

{% set imageUrl %}
    {% socialImg
        theme=2,
        title="Some Interesting Blog Post Title Text",
        fileName="theme-two",
        inputDir="./src",
        outputPath="/social-share/"
    %}
{% endset %} 

If you want to change the backgrund for a theme, provide a themeColor argument. You can also change the font color with fontColor. The styles argument is another way to style the predefined themes but specificity usually will require extremely specific selectors or !important usage (This is because the predefined themes have their own HTML and CSS which are first in the styles array).

Note: If you create a custom template of your own and pass that HTML into the input argument of socialImg, the styles you provide to styles will be the only styling (unless inline styles or internal CSS are present in the HTML) and therefore have the highest specificity.

Custom HTML templates

Using your own custom template is encouraged. Design it however you like and simply pass in that HTML and CSS to the shortcode with input and styles. The plugin will do the work of creating directories and generating images. You can pass HTML straight into the shortcode using the input argument. Provide some CSS inline with HTML or to styles along with the other required arguments to begin generating images from your custom template. If your HTML doesn't rely upon any template variables then simply pass it directly to the shortcode in the input argument like this:

{% socialImg
    input="<h1>Hello World!</h1>",
    inputType="html",
    styles=[
        "h1 { 
            color: blue 
        }"
    ],
    fileName="my-html",
    inputDir="./src",
    outputPath="/images/"
%}

If you plan to use template variables in your markup for the custom template, you can pull in HTML however you would like and then pass it into the shortcode. I recommend using {% set %} to capture HTML contents into a variable using block assignments like this:

---
title: Some Post Title
date: 2021-05-07
inputDir: ./src
fileName: my-image
outputPath: /social-share/
styles:
  - "h1 { color: #f06; }"
---

{% set html %}
    <h1>{{ title }}</h1>
    <p>Posted on {{ date }}</p>
{% endset %}

{% set imgUrl %}
    {% socialImg 
        input=html,
        inputType="html",
        fileName=fileName,
        inputDir=inputDir,
        outputPath=outputPath,
        styles=styles
    %}
{% endset %}

Check out randoma11y for some great palettes to help with designing a custom theme.

Related