ImageResponse

El constructor ImageResponse permite generar imágenes dinámicas utilizando JSX y CSS. Esto es útil para crear imágenes para redes sociales como imágenes Open Graph, tarjetas de Twitter y más.

Referencia

Parámetros

Los siguientes parámetros están disponibles para ImageResponse:

import { ImageResponse } from 'next/og'

new ImageResponse(
  element: ReactElement,
  options: {
    width?: number = 1200
    height?: number = 630
    emoji?: 'twemoji' | 'blobmoji' | 'noto' | 'openmoji' = 'twemoji',
    fonts?: {
      name: string,
      data: ArrayBuffer,
      weight: number,
      style: 'normal' | 'italic'
    }[]
    debug?: boolean = false

    // Opciones que se pasarán a la respuesta HTTP
    status?: number = 200
    statusText?: string
    headers?: Record<string, string>
  },
)

Puedes encontrar ejemplos en el Vercel OG Playground.

Funcionalidades HTML y CSS soportadas

ImageResponse admite propiedades CSS comunes incluyendo flexbox y posicionamiento absoluto, fuentes personalizadas, ajuste de texto, centrado e imágenes anidadas.

Consulta la documentación de Satori para ver la lista de funcionalidades HTML y CSS soportadas.

Comportamiento

  • ImageResponse utiliza @vercel/og, Satori y Resvg para convertir HTML y CSS a PNG.
  • Solo se admite flexbox y un subconjunto de propiedades CSS. Diseños avanzados (ej. display: grid) no funcionarán.
  • Tamaño máximo de paquete de 500KB. Este tamaño incluye tu JSX, CSS, fuentes, imágenes y otros recursos. Si excedes el límite, considera reducir el tamaño de los recursos o cargarlos en tiempo de ejecución.
  • Solo se admiten formatos de fuente ttf, otf y woff. Para maximizar la velocidad de análisis, se prefieren ttf u otf sobre woff.

Ejemplos

Manejadores de Ruta (Route Handlers)

ImageResponse puede usarse en Route Handlers para generar imágenes dinámicamente al momento de la solicitud.

app/api/route.js
import { ImageResponse } from 'next/og'

export async function GET() {
  try {
    return new ImageResponse(
      (
        <div
          style={{
            height: '100%',
            width: '100%',
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
            justifyContent: 'center',
            backgroundColor: 'white',
            padding: '40px',
          }}
        >
          <div
            style={{
              fontSize: 60,
              fontWeight: 'bold',
              color: 'black',
              textAlign: 'center',
            }}
          >
            Bienvenido a mi sitio
          </div>
          <div
            style={{
              fontSize: 30,
              color: '#666',
              marginTop: '20px',
            }}
          >
            Generado con ImageResponse de Next.js
          </div>
        </div>
      ),
      {
        width: 1200,
        height: 630,
      }
    )
  } catch (e) {
    console.log(`${e.message}`)
    return new Response(`Error al generar la imagen`, {
      status: 500,
    })
  }
}

Metadatos basados en archivos

Puedes usar ImageResponse en un archivo opengraph-image.tsx para generar imágenes Open Graph en tiempo de compilación o dinámicamente al momento de la solicitud.

app/opengraph-image.tsx
import { ImageResponse } from 'next/og'

// Metadatos de la imagen
export const alt = 'Mi sitio'
export const size = {
  width: 1200,
  height: 630,
}

export const contentType = 'image/png'

// Generación de imagen
export default async function Image() {
  return new ImageResponse(
    (
      // Elemento JSX de ImageResponse
      <div
        style={{
          fontSize: 128,
          background: 'white',
          width: '100%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        Mi sitio
      </div>
    ),
    // Opciones de ImageResponse
    {
      // Por conveniencia, podemos reutilizar la configuración de tamaño
      // exportada en opengraph-image para establecer ancho y alto.
      ...size,
    }
  )
}

Fuentes personalizadas

Puedes usar fuentes personalizadas en tu ImageResponse proporcionando un array fonts en las opciones.

app/opengraph-image.tsx
import { ImageResponse } from 'next/og'
import { readFile } from 'node:fs/promises'
import { join } from 'node:path'

// Metadatos de la imagen
export const alt = 'Mi sitio'
export const size = {
  width: 1200,
  height: 630,
}

export const contentType = 'image/png'

// Generación de imagen
export default async function Image() {
  // Carga de fuente, process.cwd() es el directorio del proyecto Next.js
  const interSemiBold = await readFile(
    join(process.cwd(), 'assets/Inter-SemiBold.ttf')
  )

  return new ImageResponse(
    (
      // ...
    ),
    // Opciones de ImageResponse
    {
      // Por conveniencia, podemos reutilizar la configuración de tamaño
      // exportada en opengraph-image para establecer ancho y alto.
      ...size,
      fonts: [
        {
          name: 'Inter',
          data: interSemiBold,
          style: 'normal',
          weight: 400,
        },
      ],
    }
  )
}

Historial de versiones

VersiónCambios
v14.0.0ImageResponse movido de next/server a next/og
v13.3.0ImageResponse puede importarse desde next/server.
v13.0.0ImageResponse introducido mediante el paquete @vercel/og.

On this page