---
title: "Generate images"
description: "Generate images with the OpenAI API and insert them into your Tiptap editor."
canonical_url: "https://tiptap.dev/docs/ai/basic/image-generation"
---

# Generate images

Generate images with the OpenAI API and insert them into your Tiptap editor.

Generate images with AI and insert them in your document.

## Install the Image extension

Add the [`@tiptap/extension-image`](https://tiptap.dev/docs/editor/extensions/nodes/image.md) extension to your editor.

```js
import Image from '@tiptap/extension-image'
import { Editor } from '@tiptap/core'

const editor = new Editor({
  extensions: [Image],
})
```

## Generate the image on your server

Call the OpenAI API from a server-side route so your API key is not exposed to the browser. Use an image generation model such as `gpt-image-2`.

Then, store the generated image in your application's storage solution, such as S3, R2, Supabase Storage, or your own media service. Return the stored image URL to the client.

> **Avoid storing images as base64:**
>
> Storing generated images as base64 in the document is not recommended, especially in collaborative documents. Base64 images significantly increase document size, slow down syncing, and can make collaboration updates more expensive to process.

```js
import OpenAI from 'openai'

const openai = new OpenAI()

export async function POST(request) {
  const { prompt } = await request.json()

  const result = await openai.images.generate({
    model: 'gpt-image-2',
    prompt,
    size: '1024x1024',
  })

  const imageBuffer = Buffer.from(result.data[0].b64_json, 'base64')
  const imageSrc = await uploadImageToStorage(imageBuffer, {
    contentType: 'image/png',
    fileName: `generated-${Date.now()}.png`,
  })

  return Response.json({
    imageSrc,
  })
}
```

The `uploadImageToStorage` function depends on your application. It should upload the image bytes to your storage provider and return a URL that the editor can render.

## Insert the generated image

Call your server route from the client and pass the returned image source to `setImage`.

```js
async function generateAndInsertImage(prompt) {
  const response = await fetch('/api/generate-image', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ prompt }),
  })

  const { imageSrc } = await response.json()

  editor.commands.setImage({ src: imageSrc })
}
```

You can include additional attributes when inserting the image. See a [list of all available options](https://tiptap.dev/docs/editor/extensions/nodes/image.md).

```js
editor.commands.setImage({
  src: imageSrc,
  alt: prompt,
  title: prompt,
})
```
