Generate Dynamic Open Graph Images with Next.js 13.3 and Tailwind

9 min read / April 21, 2023

In today's digital world, having a strong online presence has become crucial for businesses and individuals alike. Social media platforms play a vital role in building an online presence, and the Open Graph protocol has become a standard for sharing web content on these platforms.

Open Graph protocol enables web developers to define metadata that describes how the content of a web page should be displayed when it is shared on social media platforms. Open Graph images are a vital part of this metadata as they play a crucial role in attracting users' attention to the shared content.

Unfortunately, generating Open Graph images manually for each web page is a tedious and time-consuming task. But with the release of Next.js 13.3, and the implementation of Vercel's Open Graph (OG) Image Generation into the framework, automatically generating dynamic Open Graph images has become easier than ever. Under the hood, Vercel's OG Image Generation uses Satori to convert HTML and CSS to SVG.

This article assumes that you have a basic understanding of Next.js API routes and TailwindCSS. If you are new to these technologies, I recommend you to check out their official documentation.

Create a new API route

To generate our images we will need to create an API route. To do so, create a new file called og.tsx under the pages/api directory. In this file, we will first create our function that will generate the Open Graph image by using the newly implemented ImageResponse from next/server. We also need to tell Next.js that we want this function to use the Edge Runtime by adding the export const config = { runtime: 'edge' } line before the function declaration.

You should now be able to access the generated image by visiting http://localhost:3000/api/og in your browser, and you should see the following image:

Our first generated OG Image

As you can see, we have successfully generated our first Open Graph image in a few lines of code. But we can improve what we've done so far by making the content dynamic and by making the image look better.

Dynamic Content

Since we are using Next.js API routes, we can easily access the query parameters of the request, we just need to keep in mind that we are using the Edge Runtime that doesn't support the request.query object. Instead, we need to parse the request.url to get the query parameters. Let's replace the title and description variables that we defined earlier with the following code:

Now, if we visit http://localhost:3000/api/og?title=Dynamic%20title&description=Dynamic%20description in our browser, we should see that the content of the image has changed to match the query parameters.

Let's make it look better

Generating dynamic Open Graph images is great, but it's not what will make your content stand out from the crowd. To do so, we need to make our images look better.

For the rest of this article, we will reproduce my own Open Graph image that I use on my website. Here is what it looks like:

The OG image we will reproduce

To achieve this result, we will use the following tools:

  1. TailwindCSS to style our image
  2. Custom fonts from Google Fonts
  3. Local images for our background


To use TailwindCSS in our Open Graph image, we will use the experimental implementation of TailwindCSS in Vercel's OG package. Instead of using style objects, we will use the tw attribute and TailwindCSS classes to style our image.

Let's replace the style attribute of our HTML tags with the following code:

You should have the same result as before, but now we are using TailwindCSS classes to style our image, quite convenient, isn't it ?

The only limitation is that we can only use some specific classes of TailwindCSS, which correspond to the ones supported in the Satori package. You can find the list of supported CSS properties here.

Custom fonts

To match the font you are using on you own website and keep a consistent look and feel between your website and your Open Graph images, you can use custom fonts. To do so, we will need to have the source of the font file located in our project. In my case, I am using the Inter font from Google Fonts, so I will need to download the font files for each font weight and font style that I am using and place them inside my public/fonts folder.

Then, we need to import the font data in our API route. To do so, we will use the fetch function to get the font data and the ArrayBuffer object to convert the data to an ArrayBuffer object. We will also need to add a font key in the options object of the ImageResponse function.

We will have the following code:

Local images

The same import process can be used to import local images. In my case, I am using a local image for the background of my Open Graph image. To do so, I will need to place the image in my public/images folder and import it in my API route. Then I will just need to set the image data in the src attribute of the img tag.

After adding my background, my logo as an SVG and with a bit of styling, you should have the following code:

And if you go to https://localhost:3000/api/og?title=Hello%20World&description=This%20is%20our%20first%20Open%20Graph%20image, you should see the following image:

The final OG image

How to use it

In order to use this image, you can simply add the endpoint in your metadata object inside the generateMetadata function:


In this article, we have seen how to create an Open Graph image with Next.js 13.3 and Tailwind CSS. It is actually pretty straightforward, and you can use this code as a solid base to create your own Open Graph images.


© 2023 - Simon Bellucci