Create a new Next.js Project
Open your terminal and write this following command:
pnpm create next-app dynamic-og-background
Next.js generator will be show like this:
✔ What is your project named? … .
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes
Change your directory with this following command:
cd dynamic-og-background
and open with your code editor or IDE.eg:
code .
or
webstorm .
Project Structure
├── README.md
├── next-env.d.ts
├── next.config.js
├── package.json
├── postcss.config.js
├── public
│ ├── og-bg.png // I created this image to use as background
│ ├── next.svg
│ └── vercel.svg
├── src
│ └── app
│ ├── api // I created this folder to store my api routes
│ │ └── og
│ │ └── route.tsx // Here is my og route
│ ├── fonts // I created this folder to store my fonts
│ │ └── mono.ttf // Here am using outfit font
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.tsx
│ └── page.tsx
├── tailwind.config.ts
└── tsconfig.json
├── pnpm-lock.yaml
I created api folder to store my api routes and also created fonts folder to store my fonts. You can use any font you want.
Implement the dynamic opengraph route
import { ImageResponse } from 'next/og';
import { NextRequest } from 'next/server';
export const runtime = 'edge';
export async function GET(req: NextRequest) {
const { searchParams } = req.nextUrl;
const postTitle = searchParams.get('title');
const font = fetch(new URL('../mono.ttf', import.meta.url)).then((res) =>
res.arrayBuffer()
);
const fontData = await font;
return new ImageResponse(
(
<div
style={{
height: '100%',
width: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'flex-start',
padding: '100',
justifyContent: 'flex-start',
backgroundImage: `https://exmaple.com/og-bg.png)`,
}}
>
<p
style={{
display: 'flex',
fontSize: 100,
fontFamily: 'Jetbrains Mono',
letterSpacing: '-0.05em',
fontWeight: '7000',
fontStyle: 'normal',
color: 'black',
lineHeight: '120px',
whiteSpace: 'pre-wrap',
textTransform: 'capitalize',
}}
>
{postTitle}
</p>
</div>
),
{
width: 1920,
height: 1080,
fonts: [
{
name: 'Jetbrains Mono',
data: fontData,
style: 'normal',
},
],
}
);
}
Output
<meta property="og:image" content="<generated>" />
<meta property="og:image:alt" content="About Acme" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
Code Explanation
- Import the necessary modules and constants.
- Set Runtime: Declare runtime as 'edge'.
- Define an asynchronous function to handle GET requests.
- Use the fetch API to get the Outfit font data and convert it to an array buffer.
- Generate an ImageResponse object with dynamic JSX content.
- Specify options for the ImageResponse, including width, height, and font details.
Test your dynamic opengraph route
- pnpm dev
- open your browser and enter your dynamic open graph route in your browser address bar.
- example: http://localhost:3000/og?title=hello
For more information, check out the official documentation on Open Graph.