Podcast - Vercel OG Image template

Create a new API endpoint:

// pages/api/og/podcast.jsx

import React from "react";
import { ImageResponse } from "@vercel/og";

export const config = {
  runtime: "experimental-edge",
};

export default async function handler(req) {
  try {
    const { searchParams } = new URL(req.url);

    // dynamic params
    const title = searchParams.has("title")
      ? searchParams.get("title")?.slice(0, 100)
      : "My default title";
    const image = searchParams.get("image") || "";
    const season = searchParams.get("season") || "1";
    const episode = searchParams.get("episode") || "1";
    const guest = searchParams.get("guest") || "Include a guest name";
    const duration = searchParams.get("duration") || "0";

    return new ImageResponse(
      (
        <div tw="h-full w-full flex items-start justify-start bg-yellow-100 p-20">
          <div tw="flex h-full items-center w-full">
            <div tw="flex-1 flex flex-col mr-20">
              <p tw="font-bold mb-0">
                Season {season} • Episode {episode}
              </p>
              <h1 tw="text-6xl">{title}</h1>
              <p tw="text-red-500 text-lg mt-0">
                {guest}{duration}min
              </p>
            </div>
            {image ? (
              <div tw="flex relative">
                <svg
                  tw="absolute top-[-300px] left-[-100px] opacity-20"
                  id="visual"
                  viewBox="0 0 900 600"
                  width="900"
                  height="600"
                  version="1.1"
                >
                  <g transform="translate(444.3593826782917 273.8643784322123)">
                    <path
                      fill="#ef4444"
                      d="M186.1 -166.4C230.8 -141.4 249.4 -70.7 237.7 -11.7C226 47.4 184.1 94.8 139.4 139.9C94.8 185.1 47.4 228 -2.2 230.3C-51.9 232.5 -103.7 194 -149.2 148.9C-194.7 103.7 -233.9 51.9 -229.5 4.4C-225.1 -43.1 -177.3 -86.3 -131.8 -111.3C-86.3 -136.3 -43.1 -143.1 13.8 -156.9C70.7 -170.7 141.4 -191.4 186.1 -166.4"
                    ></path>
                  </g>
                </svg>
                <img
                  style={{ objectFit: "cover" }}
                  tw="mx-auto border-8 border-red-500 w-[300px] h-[300px] rounded-full"
                  src={image}
                />
              </div>
            ) : null}
          </div>
        </div>
      ),
      {
        width: 1200,
        height: 627,
      }
    );
  } catch (e) {
    console.log(`${e.message}`);
    return new Response(`Failed to generate the image`, {
      status: 500,
    });
  }
}

You can then create new dynamic images by passing the following parameters to the API endpoint:

const title =
  "How the Bluth Company built thousands of homes in Iraq with no VC money";
const season = 1;
const episode = 12;
const guest = "Michael Bluth - The Bluth Company";
const duration = 40;
const image =
  "https://static.wikia.nocookie.net/arresteddevelopment/images/4/42/5x15_-_Michael_Bluth_01.jpg";

return (
  <img
    src={`/api/og/podcast?title=${title}&season=${season}&episode=${episode}&guest=${guest}&duration=${duration}&image=${image}`}
  />
);

// or

return (
  <meta
    property="og:image"
    content={`www.yourdomain.com/api/og/podcast?title=${title}&season=${season}&episode=${episode}&guest=${guest}&duration=${duration}&image=${image}`}
  />
);
Currently, passing imgix/unsplash images as a parameter can be a bit tricky. You should amend the URL before passing it to the endpoint. For example, this URL https://images.unsplash.com/photo-1476820865390-c52aeebb9891?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1770&q=80 should be amended to https://images.unsplash.com/photo-1476820865390-c52aeebb9891?w=1770&q=80&fm=png
  • Remove auto=format, fit=crop, ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8, ixlib=rb-1.2.1 param
  • Add fm=png params
When passing images via the url parameters, make sure that they are not over ~400 KB in size, due to limitations of Vercel's edge functions.
If you are storing images locally within your codebase, you can get around the 1MB limitation of Vercel's edge function by referencing the image locally. You can store the image in the /public and use src={process.env.VERCEL_URL/image.jpg} within your API endpoint.

If you want to use your own custom fonts for this template, follow this example.
More Vercel OG templates

Receive an email when we publish a new template

Max 1-2x times per month.