Generate images
Generate images with AI and insert them in your document.
Install the Image extension
Add the @tiptap/extension-image extension to your editor.
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.
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.
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.
editor.commands.setImage({
src: imageSrc,
alt: prompt,
title: prompt,
})