# We built an internal tool to generate changelog images for social media

-   [

    ![](https://res.cloudinary.com/dmukukwp6/image/upload/c_scale,w_50/Cory_0625c10074)

    Cory Watilo](/community/profiles/30200.md)

Aug 28, 2024

PostHog's marketing team recently [created a plan](https://github.com/PostHog/meta/issues/218) to improve our social media presence. One of the [ideas](https://github.com/PostHog/meta/issues/232) was to share our [changelog updates](/changelog.md) in a more visual way – using a graphic instead of just a text-based post.

## Why image-based updates?

Image-based posts perform better on X than linking out to another site. [![](https://res.cloudinary.com/dmukukwp6/image/upload/v1741770588/thumbnail_ian_31bf16ef7d_c3339bc255.png)Ian Vanagas![](https://res.cloudinary.com/dmukukwp6/image/upload/v1741770588/thumbnail_ian_31bf16ef7d_c3339bc255.png)Ian Vanagas](/community/profiles/29296.md) originally trialed this with "visual essays". After posting a few of these, we quickly updated the design to match our brand.

![Visual essay example](https://res.cloudinary.com/dmukukwp6/image/upload/visual_essay_d3b07fbd64.png)

So that works great for the occasional visual essay, but for changelog posts, we had a problem... we didn't have the bandwidth to create images for every new changelog post – nor should design be a blocker for the marketing team. And I didn't want to force anyone to use Figma to create these images.

So we started to think... could we productize this so our team could generate high-quality images automatically? After all, our [changelog updates](/changelog.md) already include most of the information we'd need.

A couple years ago, we had done something similar for auto-generating [custom open graph images](/blog/dynamic-open-graph-images.md) for most pages on the website, so we thought... why not do something similar here?

![Github discussion](https://res.cloudinary.com/dmukukwp6/image/upload/synergy_997b3b5c83.png)

## Figma mockup

So I got to work, mocking up a template that would pull information from our self-rolled CMS.

![Changelog image mockup](https://res.cloudinary.com/dmukukwp6/image/upload/changelog_mockup_0c8bcba585.png)

## How we did it

I wrote up [an issue](https://github.com/PostHog/posthog.com/issues/9149) outlining how I thought we'd be able to combine data from changelog updates, small teams, and team members for use in the rendered images.

### Changelog data

Our changelog entries already included `title`, `description`, `screenshot`, `update_type`, and associated `product` and `team`.

![Changelog editor](https://res.cloudinary.com/dmukukwp6/image/upload/changelog_editor_ef77bb982b.png)

### Product branding

Each PostHog product has an icon and color associated with it. These are defined in a JSON file that builds our navigation submenus.

PostHog AI

```
{
  name: 'Data warehouse',
  url: '/docs/data-warehouse',
  color: 'lilac',
  icon: 'IconDatabase',
}
```

(The `color` maps to a HEX value defined in Tailwind.)

### Customization

Then it just comes down to visual polish, so we added a few options.

![Changelog image options](https://res.cloudinary.com/dmukukwp6/image/upload/edit_options_787a9644c6.png)

### Hedgehogs

And what PostHog graphic wouldn't be complete without a hedgehog?

Recently, [![](https://res.cloudinary.com/dmukukwp6/image/upload/v1779124810/thumbnail_Property_1_lottie_c_2c6f702c4a.png)Lottie Coxon![](https://res.cloudinary.com/dmukukwp6/image/upload/v1779124810/thumbnail_Property_1_lottie_c_2c6f702c4a.png)Lottie Coxon](/community/profiles/27881.md) organized our [hedgehog library](https://www.figma.com/design/I0VKEEjbkKUDSVzFus2Lpu/Hoggies?node-id=2226-55&t=UfQboIrCRcRuvSSK-1) and named each hedgehog.

This made it easy for our front end developer [![](https://res.cloudinary.com/dmukukwp6/image/upload/v1688574894/thumbnail_eli_cbbeee7496.png)Eli Kinsey![](https://res.cloudinary.com/dmukukwp6/image/upload/v1688574894/thumbnail_eli_cbbeee7496.png)Eli Kinsey](/community/profiles/28804.md) to export them and create a searchable library (based off the filenames).

Now we can choose any hedgehog image from our library – as long as it's uploaded to a folder in Cloudinary.

### Generating the image

We used [html-to-image](https://github.com/bubkoo/html-to-image) to render the final product. When a team member clicks the *download* button, the image is generated [in a very clever way](https://github.com/bubkoo/html-to-image#how-it-works), then downloaded to the client.

## The final product

And voila, here's an example of our first image produced with this new tool. You should [check it out on X](https://twitter.com/posthog/status/1828458717810983330) - and give us a follow while you're there!

![Changelog post on X](https://res.cloudinary.com/dmukukwp6/image/upload/changelog_post_598cd1a031.png)

> PostHog is the leading platform for building self-driving products. With a full suite of developer tools – [AI observability](/ai-observability.md), [product analytics](/product-analytics.md), [session replay](/session-replay.md), [feature flags](/feature-flags.md), [experiments](/experiments.md), [error tracking](/error-tracking.md), [logs](/logs.md), and more – PostHog captures all the context agents need to diagnose problems, uncover opportunities, and ship fixes. A [data warehouse](/data-stack.md) and [CDP](/cdp.md) tie it all together, unifying that context into one source agents can read across. You can steer it all from [Slack](/slack.md), [the web app](/ai.md), the desktop ([PostHog Desktop](/desktop.md)), or your own editor via [the MCP](/mcp.md).

### Community questions

Ask a question