(Table of contents & other stuff:  )

How to create A/B testable meta-images

How to create 100% hallucination-free, A/B testable Open-graph and Google Discover images for your blog and product pages. Or any page for that matter.

Why #

Open graph images and Discover-images are like the new meta-tags for web pages. That’s why I call them ‘meta-images’.

Of course all SEO-folks are familiar with trying to optimize titles and descriptions for CTR, but have you tried doing the same for images?

You should.

It’s those images that have a LOT of effect on whether folks decide to click through. This applies especially to Google Discover, but also for most or maybe even all social media channels: an image preview is shown based on usually the open graph image tag. In the case of Google Discover, it means the image should be visible on the page itself, and at least 1200px wide.

It’s not just for CTR. We know that these channels like to keep you within their walls. So there’s a branding effect there too. Being seen. Sure, you can show only your logo, but it’s better to provide some additional context … heck, it might even yield some clicks!

So for the push-click channels (like Discover) it’s for clicks; for the walled gardens it’s a combination of visibility and (some) clicks.

How #

Let me tell you how I implemented it for my own website, which is powered by CraftCMS.

In the first few versions, the whole process was way too complicated, so I eventually settled on a rather simple and not very scalable version.

If you really want to automate this for for example all PDP's of an e-commerce store, you should use a more elaborate process (more on that later). But what I have right now is suited just fine for my own needs.

I’m an automator. And I do stuff with *Findability* (formally known as SEO). So I wanted to achieve a few things normal, manual image design processes don’t do, and something ChatGPT doesn’t do either.

So here's the list of criteria.

What it should do #

The image:

  • -

    needs to dynamically reflect what’s on the page when someone lands on it: the title, the author, even the look & feel of the website

  • -

    needs to be generated automatically, so it *could* scale with some tweaks

  • -

    it needed to be 100% hallucination-free (so yeah, no ChatGPT involved). I want to control what it displays

  • -

    it needs to be cheap. Use whatever is available on the page already: the author, the title, the design system. It's actually not really a designed image, but a collection of normal page elements, put together and called an 'image' :)

The 'control' part is important.

Because if I can control it, I can A/B test it: another background, font, author image, border, title etc. See what it does, play around with it. And because it mimics the look & feel of the website, it should parse the same CSS and fonts I use on the website. It should be able to work with different types of images, like svg’s, png’s, video thumbnails, whatever is displayed.

The solution #

In CraftCMS, I send a ‘create a screenshot of this URL’ signal to an external screenshot-taker when necessary. That’s the idea.

So I generate a custom output of the article on another, hidden, URL. That output is another version of the same article. It’s not even an API: it’s the same database and the same website, with the same fonts, templates, images, rendering.

The idea being: if I can show it in a browser, no matter how my website is built, I can take a screenshot of it, and use that as open graph image.

When I save an article in the CraftCMS control panel, an event is fired ( I use the Preparse field for this) that checks if the image needs to be updated. If so, it sends a request to an external screenshot tool, with the URL it should take the screenshot from as input. The event waits for the screenshot tool to finish, and saves the response, which is the URL of the screenshot image that was just taken.

The flow #

So right now, I use the following steps:

1. Custom Article Output (Hidden URL)

Article is rendered on a hidden route using the same templates, fonts, and design as the public version.

2. Event Fired on Save

When saved, an event checks if the Open Graph image needs to be updated.

3. Screenshot Request

If needed, CraftCMS sends the hidden URL to the external screenshot tool.

4. Screenshot Taken

The external service loads the page, takes the screenshot, and returns the image URL.

5. Image URL Stored

CraftCMS receives the URL and saves it as the Open Graph image for the article.

How to really scale this #

My current setup doesn't really scale. It's a prototype.

But, if you would want to scale it, there are some things to keep in mind:

  1. 1.

    Use a queue: right now, the image is generated when i hit 'save'. Instead, this process should be sent to a background process (a queue) that doesn't freeze the Control panel.

    You would also need a queue if you want to change the lay-out of all images at once, for example.

  2. 2.

    My images aren't imported into my system. The screenshot is saved and a reference is returned to the CDN that hosts them. But instead I should import them into my own file system. Which I control.

  3. 3.

    There is no CRUD baked in: I can generate a new image when needed. That's it. But I should be able to re-generate them on demand, delete obsolete ones, etc.

  4. 4.

    Now I need to hit 'save' in the config of an article. But it would be way easier if I could just select 'all articles' (or a search result) and say: 'generate for all of them'.

  5. 5.

    I use a really cheap screenshot api and let it wait for two seconds before it takes the screenshot. But it would be better, and probably faster, if it were a bit smarter and could wait for a specific element be loaded before it takes the screenshot.

  6. 6.

    And last but not least: you would need to use a feed (can be done in CraftCMS itself), webhooks for both GET and POST requests (n8n, Apify), and an import process (FeedMe in CraftCMS)

Also, beware of caches, authorization, and response formats ;)

This is just a prototype #

I believe that SEO is changing. Not just because of LLMs. But because of zero-click results. And also because of feeds and other agents that actively scan behavior and suggest stuff online in a pro-active manner.

Images play a big part in that. Just as they've always done in the real world. We should acknowledge this and find ways to optimize them. This is an attempt to do so.

Example #

Here is the image that was generated when I first published this page. As you can see I am NOT a very good designer.

BUT: it does reflect the site's theme, and it uses elements already found on this very page: The site's logo, the title of the article, a pic of the author, a background image, a small border, and a generic image I use for listings. Not bad either.

Discover- and open-graph compatible image

Automagically generated. Test-able, repeatable, improvable meta-image.

→ Call to action ←

Want more?

Then let's close the virtual gap between us by one step.