opengraph-image y twitter-image
Las convenciones de archivos opengraph-image
y twitter-image
permiten configurar imágenes para Open Graph y Twitter en un segmento de ruta.
Son útiles para establecer las imágenes que aparecen en redes sociales y aplicaciones de mensajería cuando un usuario comparte un enlace a tu sitio.
Existen dos formas de configurar imágenes para Open Graph y Twitter:
Archivos de imagen (.jpg, .png, .gif)
Para establecer la imagen compartida de un segmento de ruta, coloca un archivo de imagen opengraph-image
o twitter-image
en el segmento.
Next.js evaluará el archivo y agregará automáticamente las etiquetas correspondientes al elemento <head>
de tu aplicación.
Convención de archivo | Tipos de archivo admitidos |
---|---|
opengraph-image | .jpg , .jpeg , .png , .gif |
twitter-image | .jpg , .jpeg , .png , .gif |
opengraph-image.alt | .txt |
twitter-image.alt | .txt |
Es bueno saber:
El tamaño del archivo
twitter-image
no debe exceder 5MB, y el tamaño del archivoopengraph-image
no debe exceder 8MB. Si el tamaño de la imagen supera estos límites, la compilación fallará.
opengraph-image
Agrega un archivo de imagen opengraph-image.(jpg|jpeg|png|gif)
a cualquier segmento de ruta.
<meta property="og:image" content="<generated>" />
<meta property="og:image:type" content="<generated>" />
<meta property="og:image:width" content="<generated>" />
<meta property="og:image:height" content="<generated>" />
twitter-image
Agrega un archivo de imagen twitter-image.(jpg|jpeg|png|gif)
a cualquier segmento de ruta.
<meta name="twitter:image" content="<generated>" />
<meta name="twitter:image:type" content="<generated>" />
<meta name="twitter:image:width" content="<generated>" />
<meta name="twitter:image:height" content="<generated>" />
opengraph-image.alt.txt
Agrega un archivo acompañante opengraph-image.alt.txt
en el mismo segmento de ruta que la imagen opengraph-image.(jpg|jpeg|png|gif)
para su texto alternativo.
Acerca de Acme
<meta property="og:image:alt" content="Acerca de Acme" />
twitter-image.alt.txt
Agrega un archivo acompañante twitter-image.alt.txt
en el mismo segmento de ruta que la imagen twitter-image.(jpg|jpeg|png|gif)
para su texto alternativo.
Acerca de Acme
<meta property="twitter:image:alt" content="Acerca de Acme" />
Generar imágenes usando código (.js, .ts, .tsx)
Además de usar archivos de imagen literales, puedes generar imágenes programáticamente usando código.
Genera la imagen compartida de un segmento de ruta creando una ruta opengraph-image
o twitter-image
que exporte por defecto una función.
Convención de archivo | Tipos de archivo admitidos |
---|---|
opengraph-image | .js , .ts , .tsx |
twitter-image | .js , .ts , .tsx |
Es bueno saber:
- Por defecto, las imágenes generadas están optimizadas estáticamente (generadas en tiempo de compilación y almacenadas en caché) a menos que usen APIs dinámicas o datos no cacheados.
- Puedes generar múltiples imágenes en el mismo archivo usando
generateImageMetadata
.opengraph-image.js
ytwitter-image.js
son Manejadores de Ruta especiales que se almacenan en caché por defecto a menos que usen una API dinámica o una opción de configuración dinámica.
La forma más fácil de generar una imagen es usando la API ImageResponse de next/og
.
import { ImageResponse } from 'next/og'
import { readFile } from 'node:fs/promises'
import { join } from 'node:path'
// Metadatos de la imagen
export const alt = 'Acerca de Acme'
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(
(
// Elemento JSX de ImageResponse
<div
style={{
fontSize: 128,
background: 'white',
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
Acerca de Acme
</div>
),
// Opciones de ImageResponse
{
// Por conveniencia, podemos reutilizar la configuración de tamaño exportada
// de opengraph-image para establecer también el ancho y alto de ImageResponse.
...size,
fonts: [
{
name: 'Inter',
data: interSemiBold,
style: 'normal',
weight: 400,
},
],
}
)
}
import { ImageResponse } from 'next/og'
import { readFile } from 'node:fs/promises'
import { join } from 'node:path'
// Metadatos de la imagen
export const alt = 'Acerca de Acme'
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(
(
// Elemento JSX de ImageResponse
<div
style={{
fontSize: 128,
background: 'white',
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
Acerca de Acme
</div>
),
// Opciones de ImageResponse
{
// Por conveniencia, podemos reutilizar la configuración de tamaño exportada
// de opengraph-image para establecer también el ancho y alto de ImageResponse.
...size,
fonts: [
{
name: 'Inter',
data: interSemiBold,
style: 'normal',
weight: 400,
},
],
}
)
}
<meta property="og:image" content="<generated>" />
<meta property="og:image:alt" content="Acerca de Acme" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
Props
La función exportada por defecto recibe las siguientes props:
params
(opcional)
Un objeto que contiene los parámetros de ruta dinámica desde el segmento raíz hasta el segmento donde opengraph-image
o twitter-image
se encuentra.
export default function Image({ params }: { params: { slug: string } }) {
// ...
}
export default function Image({ params }) {
// ...
}
Ruta | URL | params |
---|---|---|
app/shop/opengraph-image.js | /shop | undefined |
app/shop/[slug]/opengraph-image.js | /shop/1 | { slug: '1' } |
app/shop/[tag]/[item]/opengraph-image.js | /shop/1/2 | { tag: '1', item: '2' } |
Retorno
La función exportada por defecto debe retornar un Blob
| ArrayBuffer
| TypedArray
| DataView
| ReadableStream
| Response
.
Es bueno saber:
ImageResponse
cumple con este tipo de retorno.
Exportaciones de configuración
Opcionalmente puedes configurar los metadatos de la imagen exportando las variables alt
, size
y contentType
desde la ruta opengraph-image
o twitter-image
.
Opción | Tipo |
---|---|
alt | string |
size | { width: number; height: number } |
contentType | string - tipo MIME de imagen |
alt
export const alt = 'El texto alternativo de mi imagen'
export default function Image() {}
export const alt = 'El texto alternativo de mi imagen'
export default function Image() {}
<meta property="og:image:alt" content="El texto alternativo de mi imagen" />
size
export const size = { width: 1200, height: 630 }
export default function Image() {}
export const size = { width: 1200, height: 630 }
export default function Image() {}
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
contentType
export const contentType = 'image/png'
export default function Image() {}
export const contentType = 'image/png'
export default function Image() {}
<meta property="og:image:type" content="image/png" />
Configuración del segmento de ruta
opengraph-image
y twitter-image
son Manejadores de Ruta especializados que pueden usar las mismas opciones de configuración de segmento de ruta que las Páginas y Layouts.
Ejemplos
Usando datos externos
Este ejemplo usa el objeto params
y datos externos para generar la imagen.
Es bueno saber: Por defecto, esta imagen generada estará optimizada estáticamente. Puedes configurar las
opciones
individuales defetch
o las opciones de segmentos de ruta para cambiar este comportamiento.
import { ImageResponse } from 'next/og'
export const alt = 'Acerca de Acme'
export const size = {
width: 1200,
height: 630,
}
export const contentType = 'image/png'
export default async function Image({ params }: { params: { slug: string } }) {
const post = await fetch(`https://.../posts/${params.slug}`).then((res) =>
res.json()
)
return new ImageResponse(
(
<div
style={{
fontSize: 48,
background: 'white',
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
{post.title}
</div>
),
{
...size,
}
)
}
import { ImageResponse } from 'next/og'
export const alt = 'Acerca de Acme'
export const size = {
width: 1200,
height: 630,
}
export const contentType = 'image/png'
export default async function Image({ params }) {
const post = await fetch(`https://.../posts/${params.slug}`).then((res) =>
res.json()
)
return new ImageResponse(
(
<div
style={{
fontSize: 48,
background: 'white',
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
{post.title}
</div>
),
{
...size,
}
)
}
Usando el runtime Node.js con recursos locales
Este ejemplo usa el runtime Node.js para obtener una imagen local en el sistema de archivos y pasarla como un ArrayBuffer
al atributo src
de un elemento <img>
. El recurso local debe colocarse en relación a la raíz de tu proyecto, no a la ubicación del archivo fuente del ejemplo.
import { ImageResponse } from 'next/og'
import { join } from 'node:path'
import { readFile } from 'node:fs/promises'
export default async function Image() {
const logoData = await readFile(join(process.cwd(), 'logo.png'))
const logoSrc = Uint8Array.from(logoData).buffer
return new ImageResponse(
(
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<img src={logoSrc} height="100" />
</div>
)
)
}
import { ImageResponse } from 'next/og'
import { join } from 'node:path'
import { readFile } from 'node:fs/promises'
export default async function Image() {
const logoData = await readFile(join(process.cwd(), 'logo.png'))
const logoSrc = Uint8Array.from(logoData).buffer
return new ImageResponse(
(
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<img src={logoSrc} height="100" />
</div>
)
)
}
Historial de versiones
Versión | Cambios |
---|---|
v13.3.0 | Se introdujeron opengraph-image y twitter-image . |