Displaying headlines in social previews with Vercel OG

Twitter/X is planning to remove headlines from social previews. To get around this limitation, Vercel OG offers a way to display article titles directly inside OG images.
Last updated on May 10, 2024
Frameworks

OG Image content, including the headline, is crucial for clickthrough rates—Vercel's image generation library can help you get around this new limitation by displaying headlines directly inside your article's Open Graph images.

In this guide, we will take a look at how you can build an OG image proxying service that can display the title of an article directly inside the OG image for your news publication.

Here's an example of a New York Times-inspired OG image built instantly with Vercel Open Graph strategies
Here's an example of a New York Times-inspired OG image built instantly with Vercel Open Graph strategies

For your convenience, we've created a template that you can clone and develop locally. Run the following command in your terminal to clone the repository:

git clone https://github.com/steven-tey/og

Once that's done, navigate to the directory, install the dependencies, and run the app:

pnpm i && pnpm dev

Next, you'll need to import the custom font that your publication uses in your news article headings. In this example, we will be using the Cheltenham Font (italic), which is the font used by the New York Times.

Once you find it, download it as .ttf or .otf format and save it in the /styles directory:

styles/
cheltenham-italic-700.ttf (NYTimes' font)

Create an API route in pages/api/og/index.tsx and paste the following code:

pages/api/og/index.tsx
import { ImageResponse } from "@vercel/og";
import { NextRequest } from "next/server";
export const config = {
runtime: "edge",
};
// Optional: replace cheltenham-italic-700.ttf with your custom font
const cheltenham = fetch(
new URL("@/styles/cheltenham-italic-700.ttf", import.meta.url)
).then((res) => res.arrayBuffer());
export default async function handler(req: NextRequest) {
const cheltenhamData = await cheltenham;
const { searchParams } = new URL(req.url);
const url = searchParams.get("url")
// fetch the title & image from your database – we are hardcoding them here
const { title, image } = {
title: "Fall Marathoners: It’s Time to Up the Miles and Find Your Pace",
image: "https://static01.nyt.com/images/2023/08/22/multimedia/21MARATHON-TRAINING-BUILDING1-blwc/21MARATHON-TRAINING-BUILDING1-blwc-facebookJumbo.jpg"
}
return new ImageResponse(
(
<div
style={{
height: "100%",
width: "100%",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
justifyContent: "center",
backgroundImage: `url(${image})`,
backgroundRepeat: "no-repeat",
backgroundSize: "cover",
fontWeight: 600,
color: "white",
}}
>
<h1
style={{
position: "absolute",
bottom: 60,
left: 80,
margin: 0,
fontSize: 50,
fontFamily: "NYT Cheltenham",
maxWidth: 900,
whiteSpace: "pre-wrap",
letterSpacing: -1,
}}
>
{title}
</h1>
</div>
),
{
width: 1050,
height: 549,
fonts: [
{
name: "NYT Cheltenham",
data: cheltenhamData,
},
],
}
);
}

Here's a quick breakdown of what's happening in the API route above:

  1. Load the custom font we downloaded in Step 2 and feed it as a prop into the API route handler.
  2. Retrieve the meta tags (title, description) for the article from your database. Alternatively, you can also feed the values as URL query parameters as well. In this example, we are hard-coding the values for a given article.
  3. Render the headline inside the OG image using the ImageResponse constructor from the @vercel/og library.

You now have an API endpoint (/api/og) that generates styled dynamic OG image with headlines directly inside them.

Resulting OG image from the code above
Resulting OG image from the code above

Vercel's OG image library is a powerful tool for you to display dynamic OG images for your app on social media.

Learn more about the applications you can build with the Vercel OG Image library by checking out the docs.

Couldn't find the guide you need?