Vercel Product Update

Vercel Product Update


We’re excited to announce Vercel OG Image Generation – a new library for generating dynamic social card images. This approach is 5x faster than existing solutions by using Vercel Edge Functions, WebAssembly, and a brand new core library for converting HTML/CSS into SVGs.



Dynamic with limits

The engagement rate of Tweets that embed a card is  40% higher . While creating and sharing static social images isn’t difficult, handling dynamic images that need to be computed and generated instantly has had limits.

We released  og-image.vercel.app  four years ago to enable developers to dynamically generate  open graph  (OG) images by taking a screenshot of an HTML page inside of a Serverless Function. It’s since been used by thousands of developers to handle their social images. While functional, this approach came with some downsides:
Difficult: This solution required launching Chromium in a Serverless Function and taking a screenshot of the given HTML page with Puppeteer. Setting up these tools was hard to implement and often led to errors.
Slow: Because Chromium needs to be compressed to fit inside a Serverless Function and then decompressed on a cold boot, it’s very slow (~4 seconds on average). This can result in slow or broken social card images.
Expensive: Spinning up an entire browser just to take a screenshot was not efficient. This led to large Function sizes, which could be expensive and waste compute.
Large: Chromium has continued to grow in the past four years. Today, it's  too large to fit in a Serverless Function .

Dynamic without limits

We’ve created a brand new open-source library  @vercel/og  to generate dynamic social card images. Vercel OG is:
Easy: No headless browser is needed. Using Vercel OG, you can define your images using HTML and CSS and automatically generate dynamic images from the generated SVGs.
Affordable: Vercel Edge Functions are ~160x cheaper than running Chromium in a Serverless Function. Further, generated images can be cached and stored at the Edge.
Fast: Vercel OG (500KB) is 100x more lightweight than Chromium + Puppeteer (50MB), which allows functions to start almost instantly. This helps ensure images are never too slow to generate and are always recognized by tools like the Open Graph Debugger.

Our results from usage on  vercel.com/docs  show Vercel OG is 5x faster in P99 TTFB (4.96s → 0.99s) and 5.3x faster in P90 (4s → 0.75s) than our previous version. Further, the code is colocated with the rest of the application for easier maintenance and updates.
Vercel OG also supports the following features:
Support for basic CSS layout, styling, and typography
Support for use in any framework or frontend application
Support for downloading font and emoji subsets from Google Fonts and other CDNs

Dynamic social images at the Edge

Vercel OG converts HTML and CSS into images.

The core engine,  Satori , can be used in modern browsers, Node.js, and Web Workers. Building on top of the core engine, Vercel OG is able to be used inside Edge environments through WebAssembly to easily create social card images.

By leveraging the React component abstraction, social cards can be co-located with the rest of your frontend codebase. For example, inside a Next.js application:
// pages/api/og.jsx
import { ImageResponse } from '@vercel/og'
export const config = {
runtime: 'experimental-edge',}
export default function () {
return new ImageResponse(
(
<div
style={{
display: 'flex',
fontSize: 128,
background: 'white',
width: '100%',
height: '100%',
}}
>
Hello, World!
</div>
)
)
}
A Next.js Edge API Route to create a dynamic social card image.
Vercel OG automatically adds the correct Cache-Control headers to ensure the image is cached at the Edge after it’s been generated.
'content-type': 'image/png'
'cache-control': 'public, immutable, no-transform, max-age=31536000'
Caching headers from a generated Vercel OG image.
Our  social card generation  previously used a compressed Chromium release to fit inside the 50mb Serverless Function limit. Due to the size of Chromium, images could take up to 5 seconds to generate, making sharing links feel slow. With Vercel OG, images render almost immediately.
— Ben Schwarz

Tailwind CSS Support

Vercel OG also includes support for using Tailwind CSS with the  tw  prop.
<div tw="flex h-full items-center bg-white justify-center">
<div tw="bg-gray-50 flex">
<div tw="flex flex-col md:flex-row w-full py-12 px-4 md:items-center justify-between p-8">
<h2 tw="flex flex-col text-3xl sm:text-4xl font-bold tracking-tight text-gray-900 text-left">
<span>Ready to dive in?</span>
<span tw="text-indigo-600">Start your free trial today.</span>
</h2>
<div tw="mt-8 flex md:mt-0">
<div tw="flex rounded-md shadow">
<a href="#" tw="flex items-center justify-center rounded-md border border-transparent bg-indigo-600 px-5 py-3 text-base font-medium text-white">Get started</a>
</div>
<div tw="ml-3 flex rounded-md shadow">
<a href="#" tw="flex items-center justify-center rounded-md border border-transparent bg-white px-5 py-3 text-base font-medium text-indigo-600">Learn more</a>
</div>
</div>
</div>
</div></div>
An example Vercel OG image, modified from the Tailwind UI marketing section.
View this example in the  Vercel OG Playground .

Dynamic ticket images for Next.js Conf

We were able to put Vercel OG Image to the test at  Next.js Conf  by creating dynamic ticket images for every attendee.

With over 78,000 tickets created so far, we’ve seen images generated on average in 800ms. That sub-second response includes loading two custom fonts, two external requests to fetch the GitHub avatar and ticket background images, as well as two embedded SVG images.

Since we have the power of CSS, it’s easy to handle wrapping names that could break the layout, as well as supporting special characters outside of the font glyph range.

Try Vercel OG Image Generation

Vercel OG Image Generation using Vercel Edge Functions is available today in public beta.





More Light Bulb

This element (collection-block) isn't supported, or may require an update to be displayed. You can try to refresh the app.