This plugin helps to create Open Graph images in Eleventy using a template language of your choice12 and CSS3 via satori. No headless browser will be harmed 😉.
Usage
Install the package:
npm install eleventy-plugin-og-image --save-dev
Add the plugin to your .eleventy.js
:
const EleventyPluginOgImage = require('eleventy-plugin-og-image');
module.exports = (eleventyConfig) => {
eleventyConfig.addPlugin(EleventyPluginOgImage, {
satoriOptions: {
fonts: [
{
name: 'Inter',
data: fs.readFileSync('../path/to/font-file/inter.woff'),
weight: 700,
style: 'normal',
},
],
},
});
};
Create an OG-image-template, using the supported HTML elements2 and CSS properties3. CSS in <style>
tags will be inlined, remote images fetched. This is an example og-image.og.njk
:
<style>
.root {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
background: linear-gradient(135deg, #ef629f, #eecda3);
}
.title {
color: white;
font-size: 80px;
margin: auto 0;
}
</style>
<div class="root">
<h1 class="title">{{ title }}</h1>
</div>
Call the ogImage
shortcode inside the <head>
in a template. The first argument is the filePath of the OG-image-template (required), second argument is for data (optional). Usage example in Nunjucks, e.g. example-page.njk
:
{% ogImage "./og-image.og.njk", { title: "Hello World!" } %}
Result
Generated OG image _site/og-images/s0m3h4sh.png
:
HTML output generated by the shortcode in _site/example-page/index.html
(can be modified via the generateHTML
option):
<meta property="og:image" content="/og-images/s0m3h4sh.png" />
For applied usage see the example.
Note The template language of the page and OG-image-template can be mixed and matched.1
Configuration
The following options can be passed when adding the plugin:
Property | Type | Default | |
---|---|---|---|
inputFileGlob |
glob |
**/*.og.* |
This must match the OG-image-templates to prevent HTML compilation. |
getOutputFileSlug |
function |
See source | Generation of the output file slug. Return must be url safe and exclude the file extension. |
outputFileExtension |
sharp output file formats | png |
|
outputDir |
string |
_site/og-images/ |
Directory into which OG images will be emitted. Change urlPath accordingly. |
urlPath |
string |
/og-images/ |
URL-prefix which will be used in returned meta-tags. Change outputDir accordingly. |
generateHTML |
function |
See source | Change the rendered HTML in pages. |
satoriOptions |
satori options | { width: 1200, height: 630, fonts: [] } |
If an OG-image-template contains text, it's required to load a font (example). |
sharpOptions |
sharp output options | undefined |
Options must be corresponding to chosen outputFileExtension . |
Development Mode
During development the OG image file name is the url slug of the page it's generated from. In production builds, a hash of the content will be used. You'll have to handle this yourself, if you pass a custom getOutputFileSlug
.
Advanced Usage
Custom Shortcode
If you would like to build your own shortcode, you can directly use the renderOgImage
function.
const { renderOgImage } = require('eleventy-plugin-og-image/render');
const { html, svg, pngBuffer } = await renderOgImage({ inputPath, data, satoriOptions, templateConfig });
Capture Output URL
If you don't want to directly generate HTML with the shortcode, you can modify the generateHTML
option to directly return the outputUrl
:
eleventyConfig.addPlugin(EleventyPluginOgImage, {
generateHTML: (outputUrl) => outputUrl,
});
Now you can capture the outputUrl
in your page, e.g. in Nunjucks:
{% setAsync "ogOutputUrl" -%}
{% ogImage "./og-image.og.njk", { title: "Hello World!" } %}
{%- endsetAsync %}
And use it anywhere below with {{ ogOutputUrl }}
.
Acknowledgements & Attributions
This plugin is deeply inspired by @vercel/og.
Furthermore, it would not be possible without:
-
Handlebars doesn't support async shortcodes and therefore can't use the
ogImage
shortcode. Nevertheless, an OG-image-template can use Handlebars (.og.hbs
). ↩ ↩2 -
Only a subset of HTML elements is supported by satori. ↩ ↩2
-
Only a subset of CSS properties are supported by yoga-layout, which is used by satori. ↩ ↩2