Our first ever, semi-official conference is tomorrow — grab your Statameet ticket now!

Social Shots

Addon by Duncan McClean

Social Shots Main Screenshot

🚧   This addon is still in beta, things may change/break while everything is worked out before a full v1 release.

Social Shots allows you to generate social sharing images dynamically. All you need is HTML, CSS & Antlers.

This repository contains the source code of Social Shots. While Social Shots itself is free and doesn't require a license, you can donate to Duncan, the developer behind it to show your appreciation.


Addon installation

  1. Install via Composer composer require doublethreedigital/social-shots
  2. Publish configuration, assets etc php artisan vendor:publish --provider="DoubleThreeDigital\SocialShots\ServiceProvider"

Puppeteer installation

Under the hood, this addon uses something called Puppeteer (via Browsershot), which provides an easy way to take screenshots via a headless version of Chrome.

Because of this, you'll also need to install Puppeteer whereever you want to run this addon, in a local environment or on your server.

We've provided some copy & paste snippets which should work for most environments. If these install steps don't work for you, please research setting up Puppeteer for your operating system.


npm install puppeteer --global

Ubuntu (works for Forge provisioned servers)

curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt-get install -y nodejs gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget libgbm-dev
sudo npm install --global --unsafe-perm puppeteer
sudo chmod -R o+rx /usr/lib/node_modules/puppeteer/.local-chromium



Social Shots provides its own configuration file. You can use this to configure the cache length and the filesystem disk.

return [

    | Caching
    | Generating social images can sometimes take a couple of seconds. To get past
    | this, Social Shots will cache the filename of the last generated social image.
    | You can configure how long you'd like the cache to be valid for. You can
    | invalidate the cache at any time.

    'cache_length' => 60, // In minutes

    | Filesystem
    | Where should generated social shots be saved to? You're free to change this
    | to any filesystem you have configured in config/filesystems.php.

    'filesystem_disk' => 'public',



Currently, the only way to use the social images generated by this addon is via the provided tag.

<!-- Facebook/Open Graph -->
<meta property="og:image" content="{{ social-shots:og }}">

<!-- Twitter -->
<meta name="twitter:image" content="{{ social-shots:twitter }}">

The tag will automatically generate a social image when a user visits a page, the URL of which will be outputted. However, its highly recommended to regularly 'warm' your social images so users don't need to wait for Puppeteer and Browsershot to do their thing. Review caching documentation.


Probably the biggest selling point (or free-ing point, as this addon is free - see what I did there) for this addon is that you can build your own social images with HTML, CSS & Antlers. The best combination in web history.

In your social image template, you can use any of the variables that would be normally available to you, as if you were in the entry's native template. Here's a really simple example, straight from my website:

<!DOCTYPE html>
        <!-- TailwindCSS for the win! -->
    <body class="bg-white bg-pattern flex flex-col items-center justify-center">
        <div class="w-4/5 mx-auto bg-white p-8">
            <h2 class="text-3xl text-center font-semibold text-gray-800 mb-4">{{ title }}</h2>
            <h2 class="text-sm text-center font-medium text-gray-800">Published on {{ date }}.</h2>

View Conventions

Social Shots will expect that your views live in a certain folder & naming structure. This is likley something that will be loosened in future versions but as of right now, it's pretty fixed.

Social Shots will work down this list in order. If it can't find one view, it'll try the next and so on. Until it can find one that exists.

  • social_shots.
  • social_shots.
  • social_shots.default


Like explained above, by default, Social Shots will generate a fresh social image for each page, on the first request after the cache has expired.

However, this comes with one big downside: the first user after the cache expires could have to wait a couple of seconds before the page loads as it waits on your server to generate the social image.

One option would be to up the cache_length option defined in your configuration file to something really long, like a year.

Another would be to 'warm' the images. This means that, on a regular basis, you could run a background job that would regenerate any social images where the cache has expired. Because this is run on the back-end, there is no affect to the user and the page load times won't be affected.

You can run the 'warming' using this command:

php please social-shots:warm

If you're running Laravel's scheduler, you can also schedule the command to run on a regular basis.

// app/Console/Kernel

protected function schedule(Schedule $schedule)

Invalidating the cache

You may also wish to invalidate the cache for a specific page. To do so, append the purge_social_shot query parameter to page URL.



From a security perspective, only the latest version will receive a security release if a vulnerability is found.

If you discover a security vulnerability within social-shots, please report it via email straight away. Please don't report security issues in the issue tracker.


  • Issue Tracker: Find & report bugs in Social Shots
  • Email: Support from the developer behind the addon