How to dynamically generate Open Graph images using Vercel OG?

4 min read
Cover Image for How to dynamically generate Open Graph images using Vercel OG?
Photo by Kevin Kanlas

On October 10th, 2022, Vercel introduced its og image generation library which makes it easier for developers deploying on Vercel to generate og images on the fly. Read the original post here.

What is an Open Graph image?

OG images are the small cards that appear when you share a link on social media. They are used to give a preview of the content that the link points to. For example, when you share a link to this blog post on Facebook, it will look like this:

Notion image

Why is it important?

We shouldn't judge a book by its cover but we do it all the time. The same goes for links. If you see a link that is shared on social media, you will most likely click on it if it looks interesting regardless of its actual content because the og image is what catches your attention. The engagement rate of tweets that embed a card is 40% higher than those that don't. The same goes for other social media platforms. Therefore, it is important to have good og images for your links.

The problem

  • Manually creating og images for every blog post is time consuming and takes away from the actual writing process.
  • Services that let you dynamically generate og images like Cloudinary might be too slow, too expensive, or too time consuming to set up.
  • Vercel's previous solution to this, released four years ago, took a screenshot of an HTML page inside of a serverless function. This implementation had too many moving parts and was therefore error prone and slow.

The solution

Use the brand new open-source library vercel/og to generate dynamic social card images.

  • It is fast and lightweight because it runs on Vercel’s edge network.
  • It uses HTML and CSS to generate the images.
  • It has support for using custom fonts.
  • It runs Satori under the hood so it can run in virtually any environment.
  • If you have a small blog you can easily live on its free tier.
  • It automatically caches the images so you don't have to worry about generating them every time.
  • Bonus: It has experimental support for tailwind.

How to use it?

  • Create a new Next.js project or navigate to your existing project.
  • Install the library using npm i vercel/og
  • Navigate to the pages/api directory and create a new file called og.js

(Since vercel/og only supports the Noto Sans font by default the example below shows how to use a custom font for your og images as well)

// pages/api/og.js
import React from "react";
import { ImageResponse } from "@vercel/og";

export const config = {
  runtime: "experimental-edge",
};
// fetching custom font stored in the public directory
const font = fetch(
  new URL('/public/fonts/Ubuntu-Bold.ttf', import.meta.url)
).then((res) => res.arrayBuffer());

export default function handler(req) {
  try {
    const { searchParams } = new URL(req.url);
		const fontData = await font;

    // dynamic params
    const title = searchParams.has("title")
      ? searchParams.get("title")?.slice(0, 100)
      : "My default title";

    const emoji = searchParams.get("emoji") || "mywebsite.com";

    return new ImageResponse(
      (
        <div tw="h-full w-full flex items-start justify-start bg-sky-50">
          <div tw="flex items-start justify-start h-full">
            <div tw="flex flex-col justify-center items-center px-20 w-full h-full text-center">
              <p tw="text-[120px] mx-auto text-center font-bold mb-0">
                {emoji}
              </p>
              <h1 tw="text-[60px] font-bold">{title}</h1>
            </div>
          </div>
        </div>
      ),
      {
        width: 1200,
        height: 627,
        // Supported options: 'twemoji', 'blobmoji', 'noto', 'openmoji', 'fluent' and 'fluentFlat'
        emoji: "twemoji",
				// Using custom font
				fonts: [
          {
            name: 'Ubuntu',
            data: fontData,
            style: 'normal',
          },
        ],
      }
    );
  } catch (e) {
    console.log(`${e.message}`);
    return new Response(`Failed to generate the image`, {
      status: 500,
    });
  }
}
  • What the above code does is take the title parameter from the url and use it to generate the og image with the specified font. If the title parameter is not present, it will use the default title.
Notion image
  • Use this in the meta tags on the components of the routes that you want this image to appear on.
<meta property="og:image" content="https://mywebsite.com/api/og?title=My%20first%20og%20image%20generated%20using%20Vercel&emoji=U+1F680" />
  • To get a feel of how this functions in a live project you can use my api link. By changing the title parameter in the url you can see the image change in real time.
  • Bonus tip: You can also use this library to generate images for your blog posts. For example, you can generate a cover image for your blog post using the title and the date of the blog post.

Some resources to get you started

  • fullstackheroes has some great templates for generating og images using vercel/og and tailwind complete with code.
  • You can play around with the library here.
  • You can find the documentation here.
  • To see how your og image will look like on different social media platforms you can use opengraph.xyz.
  • If you're using React or Next.js, you should check out the next-seo library which makes it easier to add meta tags to your blog posts.

Conclusion

There's a lot more you can do with this library but I hope this was a good starting point for you to create your own dynamic og images that stand out and lead to more people viewing your content. You can checkout the source code of how I used this library to generate og images for my blog posts here. If you have any questions, feel free to reach out to me on Twitter.

This post was last updated on Oct 06, 2023