Blog» Personalized page previews for e-mail marketing with wkhtmltoimage

Personalized page previews for e-mail marketing with wkhtmltoimage

By Thiago Campos Viana  | August 24, 2017  |  eZ Publish add-ons, Web solutions

One way to attract visitors to your site is through e-mail marketing campaigns, but sending thousands of generic e-mails might not generate the kind of returns you're hoping for. One of our clients, FindaTopDoc, needed a customized approach for its e-mail campaign targeting potential new content contributor doctors. The goal was to generate an image that would show the recipient exactly what their personal blog would look like, including their profile picture and personal details.

Here is an example of the e-mail end result:

The preview picture is the image in the centre displaying how the blog would look when it's live. Recipients wouldn't just be seeing a generic doctor's information, but they'd be seeing their own name, picture, and information. This made the marketing campaign much more impactful.

In this case, including the entire site's HTML and CSS to show a customized blog preview image in the e-mail was out of the question because it was impossible to get consistent results using e-mail-safe HTML. We needed to come up with another solution. We had already used wkhtmltopdf to generate highly customized PDFs, so we decided to try wkhtmltoimage, which is part of wkhtmltopdf. In short, our solution was to use wkhtmltoimage to take screenshots of what each doctor's page would look like.

Here's a simple proof of concept:

# installing all the necessary libraries on Ubuntu
sudo apt-get install libxrender1 xfonts-utils xfonts-base xfonts-75dpi libfontenc1 x11-common xfonts-encodings libxfont1 fontconfig
# installing wkhtmltoimage
tar xf wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
sudo mv wkhtmltox/bin/wkhtmltoimage /usr/bin/
sudo chmod a+x /usr/bin/wkhtmltoimage
sudo mv wkhtmltox/bin/wkhtmltopdf /usr/bin/
sudo chmod a+x /usr/bin/wkhtmltopdf
# Testing
wkhtmltoimage --height 900 --width 1280 test.png
# Access:

For the production code, we defined a custom (and private) URL route in our Symfony-based CMS eZ Publish that used doctor IDs that both the e-mail marketing template (in Bronto) and the CMS can look up. That way, the CMS could dynamically generate each doctor's profile page based on their ID. wkhtmltoimage would then be able to take a screenshot of each page.

# start defining a route where ID is the user id, we append preview.png so the user thinks it is a path to an image
    path: /BlogExpertProfilePreview/{id}/preview.jpg
    defaults: { _controller: SomeBaseBundle:Preview:profilePreview }

Here's the controller action that generates the image. We make use of PHP WkHtmlToPdf, which is a PHP wrapper for wkhtmltopdf.

 * Action to return the blog preview image given an user id
 * @param type $id the user id
 * @return Response the preview image binary data
public function profilePreviewAction( $id )
    $legacyKernel = $this->container->get('ezpublish_legacy.kernel');
    $image = $legacyKernel()->runCallback(
        function () use ( $id )
            // first check if the preview image for this user already exists
            $previewImagePath = "public_folder_path/{$id}.jpg";
            if( file_exists( $previewImagePath ) )
                // return the existing image
                return $previewImagePath;
            // if not, try to generate an image
            // there is an existing route which shows a preview version of a blog page
            // take the screenshot of that page and save the image
            $ini = \eZINI::instance('fatd.ini');
            $siteURL = $ini->variable('Site', 'URL');
            $image = new \mikehaertl\wkhtmlto\Image( "{$siteURL}/BlogExpertProfilePreview/{$id}");
            $options = array(
                'user-style-sheet' => 'extension_css_path/wkhtml_override.css'
                , 'width' => '1280'
                , 'height' => '935'
            $image->setOptions( $options );
            $image->type = 'jpg';
            $image->saveAs( $previewImagePath );
            \eZLog::write( "Created: {$siteURL}/{$previewImagePath}", "preview.log" );
            $url = "{$siteURL}/{$previewImagePath}";
            return $previewImagePath;
    if( $image && file_exists($image) )
        $response = new BinaryFileResponse($image);
        return $response;
    // if something goes wrong, return the default image
    response = new BinaryFileResponse('public_folder_path/default.jpg');
    return $response;

The e-mail template would load an image URL such as (where "83920" is the doctor's ID), and when the recipient opened the e-mail, the system would generate the preview image. Now that's what we call a personalized e-mail!

Join our mailing list for news, events, tips, and tools

Related Blog Posts

Generate highly customized PDFs with wkhtmltopdf and eZ Publish

One of our customer websites sells research reports where all of the content is built and managed in the eZ Publish content management system. These reports...

Read more »

How a proper multi-channel CMS approach makes Facebook Instant Articles and Google AMP easier

With eZ Publish / eZ Platform at the centre of your content management strategy, from a single interface you can manage not just your users and content,...

Read more »

Marketing automation technical review: Marketo versus HubSpot

Some time ago I wrote a blog post about integrating Salesforce and Marketo in a web marketing solution powered by a content management system (in this...

Read more »

Salesforce and Marketo integration with eZ Publish

eZ Publish is a powerful Content Management System (CMS), but you typically don't try to build Customer Relationship Management (CRM) and E-mail Marketing...

Read more »

Related Case Studies



Doctor search and bookings site,, offers a medical library content along with user generated...


blog comments powered by Disqus

Hi, we're Mugo Web - Nice to meet you!

We're a group of web experts who solve complex web problems.

Learn more about us »



Yes - we can do that.

Many years of experience with complex websites allows us to offer total solutions.

Learn more about what we can do »

We love our clients (and they love us too)

We've solved problems across North America and around the world.

Learn more about what we've done »

We tweet too

Follow us on Twitter for the latest Mugo happenings

mugo twitter page @mugo

© 2008 - 2019 Mugo Web. All rights reserved.