Create a new Next.js Project
Open your terminal and write this following command:
pnpm create next-app dynamic-og-backgroundNext.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 / YesChange your directory with this following command:
cd dynamic-og-backgroundand 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.yamlI 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.