Generate Dynamic Open Graph Images using Nextjs
Tags: nextjs, webdev, tutorial
Published: 2024-06-16 17:47:27

## Dynamic OG

[Dynamic OG](https://www.dynamicog.com/) helps developers easily create og images without needing to develop their proprietary code.

It is completely free to use and a self-hosted paid version is also available.  This tutorial serves as a base for [Dynamic OG](https://www.dynamicog.com/).

Here are some of the templates available in [Dynamic OG](https://www.dynamicog.com/). Get started with the `Simple theme` below. 

All these are dynamically generated based on the queries on the url.

Use [Dynamic OG](https://www.dynamicog.com/) for your projects/companies for free.

![Simple Theme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8v1db7bwssjc1kw62ipi.png)


![Docs Theme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xhfrmvb6ejg51lir8xvt.png)


![Blogs Theme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lphnazt5bvkeufj2m5o4.png)


![Profile Theme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nz6t0wqnduhsh2mkp14m.png)

## Getting started witht the simple theme

We're going to use `nextjs` and `ImageResponse` from `next/og` to create our simple images.


To create a new `nextjs` app 

```
npm i create-next-app
```

```
npx create-next-app@latest
```
In this simple-og project we're going to use `App Router`.  You can also find the github repo at the bottom of the blog. 

```
✔ What is your project named? … simple-og
✔ 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
Creating a new Next.js app in /Users/shrihari/testRepos/simple-og.
```

```
npm install @vercel/og
```

Inside your app folder create 2 files.

```
cd simple-og/src/app 
touch Simple.tsx
touch img/route.tsx
```

In the `Simple.tsx` file. You have to be picky with the css as the [ImageResponse](https://nextjs.org/docs/app/api-reference/functions/image-response) supports only certain types of styles. 

```ts
type TSimpleTemplate = { title: string , website: string }

export function SimpleTemplate({ t }: { t: TSimpleTemplate }) {
  return (
    <div
      style={{
        background: '#f8fafc',  color: '#334155',
        width: '100%', height: '100%',
        display: 'flex',  alignItems: 'center', 
        justifyContent: 'center', padding: "24px",
      }}>
      <div style={{
        margin: '6px', padding: "24px", width: "100%",
        borderRadius: "24px", height: "100%", fontSize: 72, 
        display: "flex", flexDirection: "column",
        border: `#334155 2px solid`, color: '#334155'
      }}>
        {t.title?.slice(0, 80)}
        <hr style={{ border: `#334155 1px solid`, width: "100%" }}></hr>
        <p style={{ fontSize: "52", fontWeight: "700", display: 'flex',
           justifyContent: 'center', color: '#334155' }}> {t.website}</p>
      </div>
    </div>
  )
}
```

In the `img/route.tsx` file 

```ts
import { SimpleTemplate } from '../Simple';
import { ImageResponse } from 'next/og'
import { NextRequest } from 'next/server'

// Route segment config
export const runtime = 'edge'

// Image generation
export async function GET(request: NextRequest) {

  const params = request.nextUrl.searchParams

  const title: string = params.get("title") || "No title";
  const website: string = params.get("website") || "No website"

  const t = { title, website }

  return new ImageResponse(
    (
      <SimpleTemplate t={t} />
    ),
    {
      width: 1200,
      height: 630,
      headers: {
        'Cache-Control': 'public, max-age=3600, immutable',
      },
    },
  )
}
```

On your browser open http://localhost:3000/simple/img?title=Every%20moment%20is%20a%20fresh%20beginning.&website=blogs.gratitude.com

Just change the queries param values to generate a dynamic image based on the queries. 

Deploy on your preferred servers. You can use vercel for free if you are using only couple thousands requests per month!

![Demo simple image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cqfhv4yje70ugxn1telh.png)

Source code on github [simple-og-image](https://github.com/ShrihariMohan/simple-og-image)

It is completely free to use all our default templates and a self-hosted paid version is also available.  This tutorial serves as a base for [Dynamic OG](https://www.dynamicog.com/).

--- 


## Self Hosted Dynamic OG Includes

- Get lifetime access for just $10 per template. Customize them to match your style. Own your templates for ever.

- Leave server setup to us. Deploy on your preferred platform: Cloudflare Workers, Netlify Functions, Vercel, or even machines.

- You own the source code of your templates. This means your designs are yours, not ours. We simply provide the tools.

Learn more about [Dynamic OG](https://www.dynamicog.com/)