Abstract image of construction area

Bridging the Gap between Gatsby and Open Graph Images

4
min read

Derive and generated Images for the Open Graph Protocol directly from React Components within your Gatsby Project.

Image of blog author
David Leitner

An introduction on how to derive Open Graph Images directly from react components during build time, without all the ceremony. This allows the creation of Cover Images for Social Media with full GraphQL query support and smooth integration into your Gatsby build pipeline.

The Open Graph Protocol

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 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:

Twitter Card
Metadata for this post provided by the Open Graph Protocol.

Metadata for this post provided by the Open Graph Protocol.

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.

The usual process of adding Open Graph Images to Gatsby Pages

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.

An improved process of adding Open Graph Images to Gatsby Pages

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) for exactly this purpose. Once it is installed and configured in your [.code]gatsby-config.js[.code] ( [.code]plugins: ["gatsby-plugin-open-graph-images"][.code]), it exposes a simple createOpenGraphImage() method which hooks into the Gatsby build pipeline:


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 [.code]https://yourdomain.com/og-image/index.png[.code]. With a library like react-helmet you can add this image to your header:


<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, 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 [.code]createPage()[.code], like providing data as a GraphQL query, or providing a [.code]context[.code].

To enhance the presence of your web content not just on social networks but across your entire frontend architecture, discover how 'Backends for Frontends' can improve your development process with customized backend solutions for your Micro Frontends.

Usage during page creation

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 [.code]createOpenGraphImage()[.code] within [.code]createPage()[.code].


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 [.code]createOpenGraphImages[.code] (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:


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. For insights into how Platform Engineering can enhance your web development projects with technologies like Gatsby, visit our service page.

Further Information:

Heading

CharactersScreenComponent