Skip to content

Images

Static Images

// ...
const handleRequest = frames(async (ctx) => {
  return {
    // ...
    image: "https://picsum.photos/seed/frames.js/1146/600",
  };
});

Dynamic Image generation

You can define a dynamic image by passing in a JSX element to image property. This uses @vercel/og library under the hood, which includes a syntax for writing tailwind CSS. You can pass in options for @vercel/og via the imageOptions property. There are certain constraints around dynamic images that you should be aware of - firstly, they can be slow, affecting the UX. Secondly, dynamic images have a size limit of 256kB, which can easily be crossed if you use an existing image inside of the dynamic image.

// ...
const handleRequest = frames(async (ctx) => {
  return {
    // ...
    image: (
      <div tw="bg-purple-800 text-white w-full h-full justify-center items-center flex">
        This is rendered as an image
      </div>
    ),
    imageOptions: {
        // ...
    }
  };
});

Using tailwind CSS rules & other quirks

The Image generation uses an experimental tailwind based system, read their docs on limitations.

Using custom fonts & font-weight

In order to use custom fonts or font weights, you need to load fonts for them in imageOptions, reference docs here. An example of how to do this, instead of using ImageResponse pass the options to imageOptions and the first argument to image.