Building Branded, Dynamic Social Images with imgix

Page Weight Report

A few weeks ago, we released our new Page Weight tool. Page Weight tells website owners exactly how much heavier their sites are when responsive design is improperly implemented or not implemented at all.

Many sites are waking up to exactly how much page weight and page speed affect the user experience. The Financial Times just finished and documented a test of how page speed affects subscription rates to their paper. Spoiler alert: poor response times negatively affected engagement and subscription rates.

As part of Page Weight, we wanted to include a simple flourish: using imgix to dynamically generate the social images for each report. These social images are important not just for sharing things on Facebook and Twitter, but many other systems as well.

Page Weight is not necessarily a tool that gets shared publicly, but rather privately with a team. Thus, we wanted to introduce some magic every time a report was shared in Slack or company chat. We did this by dynamically creating an og:image to reflect the contents of each report.

Slack convo

This is a cool effect, and something we wanted to document. This blog post covers how you can use imgix to generate dynamic og:image URLs for your site.

Working from Comps to URL

Here’s a rough outline of our process:

  • Brainstorm and sketch the ideal og:image.
  • Create a high-res comp of a sample og:image. We used Adobe Illustrator for this.
  • Move into imgix Sandbox to begin implementation and see how different text behaves when plugged in
  • Port the resulting file from Sandbox to the application. Page Weight is a Rails application, so we used imgix-rails to build the image to the Sandbox specs.

A final URL from this process can be a bit overwhelming. Let's take a look at the final output image and URL.

https://assets.imgix.net/page-weight/canvas.png?ixlib=rb-1.1.0&markscale=60&bg=212b32&mark64=aHR0cHM6Ly9hc3NldHMuaW1naXgubmV0L3BhZ2Utd2VpZ2h0L3BhZ2Vfd2VpZ2h0X3JlcG9ydF9sb2dvX21hcmsuYWk_aXhsaWI9cmItMS4xLjAmbWFya3k9MzAmbWFya3g9MzAmbWFya2FsaWduPXRvcCUyQ2xlZnQmbWFyazY0PWFIUjBjSE02THk5aGMzTmxkSE11YVcxbmFYZ3VibVYwTDNCeVpYTnphMmwwTDJsdFoybDRMWEJ5WlhOemEybDBMbkJrWmo5a2NISTlNU1ptYlQxd2JtY21jR0ZuWlQwMCZ3PTEzNjAmYmc9MDAyMTJiMzImZml0PWZpbGwmaD02NDAmZm09cG5n&w=1200&h=630&fit=crop&blend64=aHR0cHM6Ly9hc3NldHMuaW1naXgubmV0L350ZXh0P2l4bGliPXJiLTEuMS4wJnR4dDY0PVJISnBZbUppYkdVZ0xTQlRhRzkzSUdGdVpDQjBaV3hzSUdadmNpQmtaWE5wWjI1bGNuTSZ0eHRjbHI9ZmZmJnc9MTEwMCZ0eHRmb250NjQ9UkVsT0lFRnNkR1Z5Ym1GMFpTeENiMnhrJnR4dHNpemU9NzImdHh0YWxpZ249Ym90dG9tJmg9MjYw&bm=normal&bx=50&ba=bottom&markx=40&txt64=aHR0cHM6Ly9kcmliYmJsZS5jb20&txtalign=left%2Cbottom&txtsize=24&txtclr=00adea&txtpad=60&txtclip=end%2Cellipsis&by=280&txtfont64=RGluIEFsdGVybmF0ZQ&fm=png8&marky=28

That’s quite an eyeful, and definitely not something that we generate by hand. Let’s see how we arrived at the final URL.

Brainstorm and Sketch the Final Result

As with anything design-related, it helps to have an idea of your direction. We sketched out a few ideas of how we wanted this to look on a whiteboard. After a few minutes, we settled on a simple and straightforward design: something informative, light on branding, and personalized.

Whiteboard sketch of og:image

Although imgix is mostly used for cropping and resizing, in reality it’s closer to a fully-scriptable, globally-distributed version of Photoshop. We had quite a bit of flexibility in creating the final result, but enough constraint to not take things overboard.

Create High-Res Comp

The process for creating a high-resolution composition of the final product is an important optional step in any design process, whether it’s for an app, a site, or a dynamically-generated og:image. This is where we started laying pixels to a canvas to really visualize the final product.

This step was crucial because we needed to take into consideration the typefaces and variability of title and URL lengths. Our design had to accommodate titles and URLs of different lengths, so we knew we would be making use of the imgix txtclip parameter to truncate them intelligently.

Recreate Comp in Sandbox

After we had a high-resolution comp that we were happy with, we brought it into Sandbox. Much like documents or canvases in Photoshop or Illustrator, multi-layered creations in Sandbox are built from the bottom up.

First, we set up the base canvas. We used a small, transparent PNG called canvas.png that we sized and colored to match the comp.

Next, we added the blue URL to the bottom of the canvas. This will always be in the same position.

Then, we used the mark parameter to lay out the branded elements of the image. This watermark also has its own watermark, which is how we build up a multi-layer document structure. We took advantage of this to pull in the logo from the PDF file that contains all of the vector branding elements for Page Weight.

Finally, we use a blend to lay out the title of the report, with a blend mode of normal to make it behave like a watermark. The blend layer links to an image generated by the imgix Typesetting Endpoint.

We set the title text at a fixed height so that it’s limited to 2 lines. That way, setting txtalign=bottom keeps the URL text and the title text grouped together. This is where the txtclip parameter truncates the rest of the title text to prevent overflow (we’re also doing some initial truncation in the Ruby code). We used markx/marky, txtpad, and bx/ba to position the various elements absolutely to the canvas edges.

Putting that all together, we get our final result:

Port the Sandbox Result to Code

Once we had things settled in Sandbox, we moved to implementation in code.

Page Weight is a Rails project, so our implementation language is Ruby. The code snippet for generating the URL programatically takes advantage of imgix-rails.

In this example, we've already uploaded the necessary assets (canvas.png, imgix-presskit.pdf, and page_weight_report_logo_mark.ai) to the Amazon S3 bucket connected to the assets.imgix.net source.

class Report < ActiveRecord::Base
  def social_image_url
    short_title = (report.title || "").strip.size <= 70
    canvas_background_color = '212b32'
    text_color = '00adea'

    imgix_client.path('/page-weight/canvas.png').to_url(
      mark64: imgix_client.path('/page-weight/page_weight_report_logo_mark.ai').to_url(
        marky: 30,
        markx: 30,
        markalign: 'top,left',
        mark64: 'https://assets.imgix.net/presskit/imgix-presskit.pdf?dpr=1&fm=png&page=4',
        w: 1360,
        bg: canvas_background_color,
        fit: 'fill',
        h: 640,
        fm: 'png'
      ),
      blend64: imgix_client.path('/~text').to_url(
        txt64: (report.title || "").strip,
        txtclr: 'fff',
        w: 1100,
        txtfont64: 'DIN Alternate,Bold',
        txtsize: short_title ? 72 : 48,
        txtalign: 'bottom',
        h: 260
      ),
      bm: 'normal',
      bx: 50,
      ba: 'bottom',
      markx: 40,
      txt64: phantom_js_run.url,
      txtalign: 'left,bottom',
      txtsize: short_title ? 24 : 18,
      txtclr: text_color,
      txtpad: 60,
      txtclip: 'end,ellipsis',
      by: short_title ? 280 : 300,
      txtfont64: 'Din Alternate',
      fm: 'png8',
      marky: 28,
      w: 1200,
      h: 630,
      fit: 'crop',
      markscale: 60,
      bg: canvas_background_color
    )
  end

private
  def imgix_client
    @imgix_client ||= Imgix::Client.new(host: 'assets.imgix.net')
  end
end

Because we worked out all of the parameters in Sandbox ahead of time, we were able to hard-code them into the helper with confidence, completely automating generation of these images with data from the Page Weight backend. Using a client library also made it easier to cleanly express the nesting order of the layers to ensure that resizing and positioning operations take place in the right order and on the correct elements.

The result is a customized image for each unique Page Weight report, easily shareable on social media or any other platform.

The combination of mark, blend, the Typesetting Endpoint, and their associated parameters gives you the power and flexibility to create all kinds of customized images. In particular, imgix makes image personalization based on customer data straightforward, while retaining overall image enhancement and resizability for responsive design. We encourage you to experiment with building your own image compositions and look forward to seeing what you make!

Stay up to date with our blog for the latest imgix news, features, and posts.