Dynamic meta images is a Craft CMS plugin that lets you generate dynamic meta images from your website's content.
This plugin requires Craft CMS 4.0 or 5.0 or later, and PHP 8.0 or later. Additional requiremens are node, npm and puppeteers.
You can install this plugin from the Plugin Store or with Composer.
Go to the Plugin Store in your project’s Control Panel and search for “Dynamic meta images”. Then press “Install”.
Open your terminal and run the following commands:
# go to the project directory
cd /path/to/project
# tell Composer to load the plugin
composer require wayborne/dynamic-meta-images
# tell Craft to install the plugin
./craft plugin/install dynamic-meta-images
This plugin requires you to install Puppeteer
npm i puppeteer
Create the following enviroment variables in your .env
file to point at the Node and NPM binary
NODE_BINARY="/usr/bin/node"
NPM_BINARY="/usr/bin/npm"
Create a new folder inside your templates folder (for example _dynamic-meta-images
). Inside the plugins ('src/templates/examples`) you can find some example templates showcasing some techniques.
Dynamic meta images are being created from a twig/html template every time an entry gets saved. The template is rendered in a headless browser and an image is created and saved to a Craft asset sources.
- Pick a template per section: if you leave the template section empty, image generation is disabled for this section (per site)
By default the entry id will be used as file name. You can customize (per template) this by passing a title
tag inside your template:
<title>{{ entry.title }}</title>
creates a new file:@
title-of-the-entry.png
You can style your templates however you want, however it's important that all of your styling resources (css/fonts/...) have a public url. That means that for local development it's easier to use some an existing CDN:
Include the following script to your header:
<script src="https://cdn.tailwindcss.com"></script>
You can even pass it your local theme to overwrite your defeault:
Any public CDN, for example google fonts:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poetsen+One&display=swap" rel="stylesheet">
<style>
.poetsen {
font-family: "Poetsen One", sans-serif;
font-weight: 400;
font-style: normal;
}
</style>
You can find some examples in the plugin directory: src/templates/examples/
Using SEOmatic's existing api you can set the meta images:
{#-- Get the title --#}
{% set image_name = entry.id %}
{#-- Check if the asset exists --#}
{% set dynamic_meta_image = craft.assets().fileName(image_name).one() ?? null %}
{#-- Test for a public url --#}
{% if dynamic_meta_image.url %}
{#-- Set the meta image --#}
{% do seomatic.meta.seoImage(dynamic_meta_image.url) %}
{% else %}
... fallback
{% endif %}
Using SEO fields you can manually set the Facebook and Twitter image:
{#-- Get the title --#}
{% set image_name = entry.id %}
{#-- Check if the asset exists --#}
{% set dynamic_meta_image = craft.assets().fileName(image_name).one() ?? null %}
{#-- Set the meta image --#}
{% if dynamic_meta_image %}
{% do entry.setFacebookImage(dynamic_meta_image) %}
{% do entry.setTwitterImage(dynamic_meta_image) %}
{% else %}
... fallback
{% endif %}
Run npm list puppeteer
to see if it's listed there. You can also check your package.json
file and see if puppeteer
is listed under the dependencies and make sure npm install
runs without any issues.
Following the official Puppeteer docs, here are all the required dependencies for Puppeteer to run on Linux: https://pptr.dev/troubleshooting#chrome-doesnt-launch-on-linux
For Node.js: Type which node (macOS/Linux) or where node (Windows) and press Enter. This will display the path to the Node.js binary. For npm: Type which npm (macOS/Linux) or where npm (Windows) and press Enter. This will display the path to the npm binary.
All image creation is being done in the queue logs so if you experience any issues, that's a good place to check. Make sure that:
- Puppeteer is installed
- The NODE_BINARY and NPM_BINARY is set
To enable Puppeteer Headless Chrome support, add the following line to your /.ddev/config.yaml
file:
webimage_extra_packages: [ gconf-service, libasound2, libatk1.0-0, libcairo2, libgconf-2-4, libgdk-pixbuf2.0-0, libgtk-3-0, libnspr4, libpango-1.0-0, libpangocairo-1.0-0, libx11-xcb1, libxcomposite1, libxcursor1, libxdamage1, libxfixes3, libxi6, libxrandr2, libxrender1, libxss1, libxtst6, fonts-liberation, libappindicator1, libnss3, xdg-utils ].
For Apple Silicon support, you will have to override that configuration by adding a config.m1.yaml file in your ddev folder along with the config.yaml one with the following content:
webimage_extra_packages : [chromium]
web_environment:
- CPPFLAGS=-DPNG_ARM_NEON_OPT=0
- PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
- PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
Brought to you by Wayborne