Bridging the Gap between Gatsby and Open Graph Images
Tags: webdev, gatsby, opengraph, seo
Published: 2020-06-15 06:54:53

---
title: Bridging the Gap between Gatsby and Open Graph Images
published: false
description: "Bridging the Gap between Open Graph Images and Gatsby"
tags: webdev, Gatsby, OpenGraph, SEO
published: true
cover_image:
---

> ➡️ This post was originally published on the [SQUER Blog](https://www.squer.at/blog/bridging-the-gap-between-gatsby-and-open-graph-images):
https://squer.at/blog/bridging-the-gap-between-gatsby-and-open-graph-images

Gatsby has become my go-to for building static web sites, mainly due to the combination of the React ecosystem with optimized SEO and great performance. But, when it comes to content-heavy web apps, the [Open Graph Protocol](https://ogp.me/) offers an additional boost for your Gatsby project, as it provides the needed metadata to publish the best of your content on social media, or for SEO in general:

<img src="https://dev-to-uploads.s3.amazonaws.com/i/ltxvm34nqx52d2g6ut5m.png" alt="Twitter Card" width="500"/><center>_Metadata for this post provided by the [Open Graph Protocol](https://ogp.me/)._</center>
<br/>

For example, the image you see on Twitter or LinkedIn next to a posted link, is usually provided by the Open Graph Protocol. But the more you work with Gatsby and the Open Graph Protocol, the more you find out that things are not that easy, as they could or should be.

## The problem 
Usually the Open Graph Images are created manually during the content creation. This has two downsides: 
* You have a tooling gap, in terms of that you are building your content with Markdown and React templates at build time. But still, your Open Graph Images are being created manually with tools like Photoshop.
* Open Graph Images easily run out of sync with the content, as they are not updated automatically on changes of the Markdown file.

<br/><br/>
<img src="https://dev-to-uploads.s3.amazonaws.com/i/tm11adk4hghfw4xe7d9o.png" alt="The usual process of adding Open Graph Images to Gatsby Pages" width="322"/>
<br/><br/>

## The solution
A solution for both problems is to integrate the creation of Open Graph images into the Gatsby build pipeline, by providing a template for your actual page, and one for your Open Graph Image.


<br/><br/>
<img src="https://dev-to-uploads.s3.amazonaws.com/i/tr4eb03gb2yh2b8jovcy.png" alt="An improved process of adding Open Graph Images to Gatsby Pages" width="362"/>
<br/><br/>

On each change of the content, both the corresponding page and the Open Image are recreated by the usage of the given template.

## Use a Gatsby Plugin: Open Graph Images

I created a Gatsby Plugin ([gatsby-plugin-open-graph-images](https://github.com/squer-solutions/gatsby-plugin-open-graph-images)) for exactly this purpose. Once it is installed and configured in your `gatsby-config.js` (
`plugins: ["gatsby-plugin-open-graph-images"]`), it exposes a simple createOpenGraphImage() method which hooks into the Gatsby build pipeline:

```js
const { createOpenGraphImage } = require("gatsby-plugin-open-graph-images");

exports.createPages = async ({ actions }) => {
  const { createPage } = actions;

  const openGraphImage = createOpenGraphImage(createPage, {
    path: "/og-image/index.png", // (1)
    component: path.resolve(`src/templates/index.og-image.js`), // (2)
    size: {
      width: 400,
      height: 50,
    }, // (3)
    context: {
      description: "a image created with gatsby-plugin-open-graph-images",
    },
  });
};
```

There are __two important parts within this snippet__: 
* __First of all__, it creates an image under the given path _(1)_, with a given size _(3)_. The image is therefore available as `https://yourdomain.com/og-image/index.png`. With a library like react-helmet you can add this image to your header:
```jsx
<Helmet>
  <meta property="og:image" content={domain + "/og-image/index.png"} />
  <meta property="og:image:width" content="400" />
  <meta property="og:image:height" content="50" />
</Helmet>
```
_Please keep in mind, that the Open Graph Protocol requires an [absolute URI](https://stackoverflow.com/questions/9858577/open-graph-can-resolve-relative-url), which contains the domain._

* __And secondly__, it makes it possible to define a React component from which the Open Graph Image is then derived. This gives us all the feature we know from `createPage()`, like [providing data as a GraphQL query](https://www.gatsbyjs.org/docs/page-query/#provide-data-to-the-homepage--component), or providing a `context`.

## Usage during `createPage()`

As described above, the creation of Gatsby pages and the corresponding Open Graph images usually goes hand in hand. Thus, a common use case is to use `createOpenGraphImage()` within `createPage()`.

```js
const result = await graphql(`
    {
      allArtistsJson {
        nodes {
          id
          name
        }
      }
    }
  `)

  result.data.allArtistsJson.nodes.forEach(({ name, id }) => {
    createPage({
      path: `artists/${id}`,
      component: path.resolve(`src/templates/artist.js`),
      context: {
        id: id,
        ogImage: createOpenGraphImage(createPage, { // 1
          path: `og-images/artists/${id}.png`,
          component: path.resolve(`src/templates/artist-og-image.js`),
          context: { id }
        })
      }
    });
  });
```

As `createOpenGraphImages` (_1_) returns a metadata object, we can easily pass this as context to the created page. The usage in the page can then rely on the context information: 

```js
const ArtistPage = ({ data, pageContext }) => {
  return (
    <>
      <Helmet>
        <meta property="og:image" content={domain + pageContext.ogImage.path}/>
        <meta property="og:image:width" content={pageContext.ogImage.size.width}/>
        <meta property="og:image:height" content={pageContext.ogImage.size.height}/>
      </Helmet>
      ...
    </>
  );
};
```

# Conclusion 

This approach of deriving Open Graph images from React components and integrating their creation into the Gatsby build pipeline helped us to increase consistency and to improve our velocity. I hope that the idea and the plugin will serve you as well.

## Further Information: 

* __[gatsby-plugin-open-graph-images on GitHub](https://github.com/squer-solutions/gatsby-plugin-open-graph-images/)__