🖼️ Using Vercel OG Image Generation With Any Framework
Vercel's @vercel/og library allows you to generate dynamic Open Graph images for social media using Edge Functions. It supports various features such as basic CSS layouts and custom fonts.
What is OG Image
The term OG
is short for Open Graph
, which is a protocol for integrating web pages into the social graph. The OG image is often referred to as the featured image
or share image
for a webpage, as it is the image that is displayed when the page is shared on social media platforms. The OG image is important because it helps to attract the attention of users and can influence their decision to click on the shared link and visit the webpage.
Integration outside Next.js
Integration with Next.js is well documented by Vercel but a limitation of Vercel’s Edge function is that is doesn’t support the JSX syntax.
🥈Using React Elements Objects
Vercel uses Satori to convert HTML and CSS to SVG which can be used with JSX or without JSX by passing elements created by React.createElement()
.
Each JSX element is just syntactic sugar for calling
React.createElement(component, props, ...children)
. So, anything you can do with JSX can also be done with just plain JavaScript.
🥇Importing .tsx to .ts
Importing .tsx
files to .ts
can be a useful way to avoid writing React element objects when working with Vercel’s Edge function.
By importing your .tsx
files into your .ts
files, you can take advantage of the benefits of JSX
syntax without having to worry about the Edge function’s lack of support for JSX
. This can make your code easier to read and write, especially if you are working with complex React components.
Let’s take a look at an example of how you might do this in your code.
First, let’s create a simple OgComponent
in a .tsx
file at api/OgComponent.tsx
:
// This component accepts a title string as a prop
export const OgComponent = (title: string) => (
// This JSX syntax is equivalent to calling React.createElement()
<div
style={{
fontSize: 128,
background: '#282A36',
color: '#50FA7B',
width: '100%',
height: '100%',
display: 'flex',
textAlign: 'center',
alignItems: 'center',
justifyContent: 'center',
}}>
{title}
</div>
);
// This component accepts a title string as a prop
export const OgComponent = (title: string) => (
// This JSX syntax is equivalent to calling React.createElement()
<div
style={{
fontSize: 128,
background: '#282A36',
color: '#50FA7B',
width: '100%',
height: '100%',
display: 'flex',
textAlign: 'center',
alignItems: 'center',
justifyContent: 'center',
}}>
{title}
</div>
);
Now we can import OgComponent
to our edge function at api/[FUNCTION_NAME].ts
:
import { ImageResponse } from '@vercel/og';
// Import the OgComponent from the .tsx file
import { OgComponent } from './ogComponent';
export const config = {
runtime: 'edge',
};
export default async function (req: Request) {
// Parse the query parameters from the request URL
const { searchParams } = new URL(req.url);
// Get the "title" query parameter, or use "Default Text"
const title = searchParams.get('title') ?? 'Default Text';
// Use the OgComponent in our Edge function
return new ImageResponse(OgComponent(title), {
width: 1200,
height: 600,
});
}
import { ImageResponse } from '@vercel/og';
// Import the OgComponent from the .tsx file
import { OgComponent } from './ogComponent';
export const config = {
runtime: 'edge',
};
export default async function (req: Request) {
// Parse the query parameters from the request URL
const { searchParams } = new URL(req.url);
// Get the "title" query parameter, or use "Default Text"
const title = searchParams.get('title') ?? 'Default Text';
// Use the OgComponent in our Edge function
return new ImageResponse(OgComponent(title), {
width: 1200,
height: 600,
});
}
By importing the OgComponent
from the .tsx
file, we can use JSX syntax to create a React element for the component and pass it to the ImageResponse
constructor. This allows us to take advantage of the benefits of JSX syntax while still using the Edge function.
Usage
After you have deployed the edge function to you should be able to browse to [DOMAIN]/api/[FUNCTION_NAME]?title=DYNAMIC_TEXT
to see the generated image.
For example browsing to https://htomar.dev/api/ogDemo?title=Hello World!🌏 will generate this image.
To create the web content for your social media post using the Open Graph Protocol, you can follow these steps:
- In the
<head>
of your webpage, create a<meta>
tag. - Add a
property
attribute to the<meta>
tag with the valueog:image
. - Add a
content
attribute to the<meta>
tag with the absolute path of the/api/og
endpoint as the value.
<head>
<title>Hello world 🌏</title>
<meta
property="og:image"
content="https://htomar.dev/api/ogDemo?title=Hello World!" />
</head>
<head>
<title>Hello world 🌏</title>
<meta
property="og:image"
content="https://htomar.dev/api/ogDemo?title=Hello World!" />
</head>