<Image>

Ejemplos

Bueno saber: Si estás usando una versión de Next.js anterior a la 13, deberás consultar la documentación de next/legacy/image ya que el componente fue renombrado.

Esta referencia de API te ayudará a entender cómo usar las props y opciones de configuración disponibles para el Componente de Imagen. Para características y uso, consulta la página del Componente de Imagen.

app/page.js
import Image from 'next/image'

export default function Page() {
  return (
    <Image
      src="/profile.png"
      width={500}
      height={500}
      alt="Foto del autor"
    />
  )
}

Props

Aquí hay un resumen de las props disponibles para el Componente de Imagen:

PropEjemploTipoRequerido
srcsrc="/profile.png"String
widthwidth={500}Entero (px)
heightheight={500}Entero (px)
altalt="Foto del autor"String
loaderloader={imageLoader}Función-
fillfill={true}Booleano-
sizessizes="(max-width: 768px) 100vw"String-
qualityquality={80}Entero (1-100)-
prioritypriority={true}Booleano-
placeholderplaceholder="blur"String-
stylestyle={{objectFit: "contain"}}Objeto-
onLoadingCompleteonLoadingComplete={img => done())}Función-
onLoadonLoad={event => done())}Función-
onErroronError(event => fail()}Función-
loadingloading="lazy"String-
blurDataURLblurDataURL="data:image/jpeg..."String-

Props Requeridas

El Componente de Imagen requiere las siguientes propiedades: src, width, height y alt.

app/page.js
import Image from 'next/image'

export default function Page() {
  return (
    <div>
      <Image
        src="/profile.png"
        width={500}
        height={500}
        alt="Foto del autor"
      />
    </div>
  )
}

src

Debe ser uno de los siguientes:

  • Un archivo de imagen importado estáticamente
  • Una cadena de ruta. Puede ser una URL externa absoluta o una ruta interna dependiendo de la prop loader.

Cuando se usa una URL externa, debes agregarla a remotePatterns en next.config.js.

width

La propiedad width representa el ancho renderizado en píxeles, por lo que afectará el tamaño aparente de la imagen.

Requerido, excepto para imágenes importadas estáticamente o imágenes con la propiedad fill.

height

La propiedad height representa la altura renderizada en píxeles, por lo que afectará el tamaño aparente de la imagen.

Requerido, excepto para imágenes importadas estáticamente o imágenes con la propiedad fill.

alt

La propiedad alt se utiliza para describir la imagen para lectores de pantalla y motores de búsqueda. También es el texto de respaldo si las imágenes están deshabilitadas o ocurre un error al cargar la imagen.

Debe contener texto que pueda reemplazar la imagen sin cambiar el significado de la página. No está destinado a complementar la imagen y no debe repetir información que ya se proporcione en los subtítulos arriba o debajo de la imagen.

Si la imagen es puramente decorativa o no está destinada al usuario, la propiedad alt debe ser una cadena vacía (alt="").

Aprende más

Props Opcionales

El componente <Image /> acepta una serie de propiedades adicionales más allá de las requeridas. Esta sección describe las propiedades más comúnmente utilizadas del componente de Imagen. Encuentra detalles sobre propiedades menos utilizadas en la sección Props Avanzadas.

loader

Una función personalizada utilizada para resolver URLs de imágenes.

Un loader es una función que devuelve una cadena de URL para la imagen, dados los siguientes parámetros:

Aquí hay un ejemplo de uso de un loader personalizado:

'use client'

import Image from 'next/image'

const imageLoader = ({ src, width, quality }) => {
  return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}

export default function Page() {
  return (
    <Image
      loader={imageLoader}
      src="me.png"
      alt="Foto del autor"
      width={500}
      height={500}
    />
  )
}

Alternativamente, puedes usar la configuración loaderFile en next.config.js para configurar cada instancia de next/image en tu aplicación, sin pasar una prop.

fill

fill={true} // {true} | {false}

Un booleano que hace que la imagen llene el elemento padre, lo cual es útil cuando el width y height son desconocidos.

El elemento padre debe asignar position: "relative", position: "fixed" o position: "absolute" en el estilo.

Por defecto, el elemento img se asignará automáticamente con el estilo position: "absolute".

Si no se aplican estilos a la imagen, la imagen se estirará para ajustarse al contenedor. Puedes preferir establecer object-fit: "contain" para una imagen que se ajuste al contenedor y preserve la relación de aspecto.

Alternativamente, object-fit: "cover" hará que la imagen llene todo el contenedor y se recorte para preservar la relación de aspecto. Para que esto se vea correctamente, el estilo overflow: "hidden" debe asignarse al elemento padre.

Para más información, consulta también:

sizes

Una cadena, similar a una consulta de medios, que proporciona información sobre el ancho que tendrá la imagen en diferentes puntos de interrupción. El valor de sizes afectará en gran medida el rendimiento de las imágenes que usan fill o que están estilizadas para tener un tamaño responsivo.

La propiedad sizes sirve para dos propósitos importantes relacionados con el rendimiento de la imagen:

  • Primero, el valor de sizes es utilizado por el navegador para determinar qué tamaño de imagen descargar, del srcset generado automáticamente por next/image. Cuando el navegador elige, aún no conoce el tamaño de la imagen en la página, por lo que selecciona una imagen que tenga el mismo tamaño o más grande que el viewport. La propiedad sizes te permite decirle al navegador que la imagen será en realidad más pequeña que el ancho completo de la pantalla. Si no especificas un valor de sizes en una imagen con la propiedad fill, se usará un valor predeterminado de 100vw (ancho completo de la pantalla).
  • Segundo, la propiedad sizes cambia el comportamiento del valor srcset generado automáticamente. Si no hay un valor de sizes presente, se genera un srcset pequeño, adecuado para una imagen de tamaño fijo (1x/2x/etc). Si se define sizes, se genera un srcset grande, adecuado para una imagen responsiva (640w/750w/etc). Si la propiedad sizes incluye tamaños como 50vw, que representan un porcentaje del ancho del viewport, entonces el srcset se recorta para no incluir valores que sean demasiado pequeños para ser necesarios.

Por ejemplo, si sabes que tu estilo hará que una imagen tenga el ancho completo en dispositivos móviles, en un diseño de 2 columnas en tabletas y en un diseño de 3 columnas en escritorios, debes incluir una propiedad sizes como la siguiente:

import Image from 'next/image'

export default function Page() {
  return (
    <div className="grid-element">
      <Image
        fill
        src="/example.png"
        sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
      />
    </div>
  )
}

Este ejemplo de sizes podría tener un efecto dramático en las métricas de rendimiento. Sin el 33vw en sizes, la imagen seleccionada del servidor sería 3 veces más ancha de lo necesario. Debido a que el tamaño del archivo es proporcional al cuadrado del ancho, sin sizes el usuario descargaría una imagen que es 9 veces más grande de lo necesario.

Aprende más sobre srcset y sizes:

quality

quality={75} // {número 1-100}

La calidad de la imagen optimizada, un entero entre 1 y 100, donde 100 es la mejor calidad y por lo tanto el mayor tamaño de archivo. Por defecto es 75.

priority

priority={false} // {false} | {true}

Cuando es verdadero, la imagen se considerará de alta prioridad y se precargará. La carga diferida se desactiva automáticamente para las imágenes que usan priority.

Debes usar la propiedad priority en cualquier imagen detectada como el elemento Largest Contentful Paint (LCP). Puede ser apropiado tener múltiples imágenes prioritarias, ya que diferentes imágenes pueden ser el elemento LCP para diferentes tamaños de viewport.

Solo debe usarse cuando la imagen es visible arriba del pliegue. Por defecto es false.

placeholder

placeholder = 'empty' // "empty" | "blur" | "data:image/..."

Un marcador de posición para usar mientras la imagen se carga. Los valores posibles son blur, empty o data:image/.... Por defecto es empty.

Cuando es blur, se usará la propiedad blurDataURL como marcador de posición. Si src es un objeto de una importación estática y la imagen importada es .jpg, .png, .webp o .avif, entonces blurDataURL se completará automáticamente, excepto cuando la imagen se detecte como animada.

Para imágenes dinámicas, debes proporcionar la propiedad blurDataURL. Soluciones como Plaiceholder pueden ayudar con la generación de base64.

Cuando es data:image/..., la URL de datos se usará como marcador de posición mientras la imagen se carga.

Cuando es empty, no habrá marcador de posición mientras la imagen se carga, solo espacio vacío.

Pruébalo:

Props Avanzadas

En algunos casos, puedes necesitar un uso más avanzado. El componente <Image /> acepta opcionalmente las siguientes propiedades avanzadas.

style

Permite pasar estilos CSS al elemento de imagen subyacente.

components/ProfileImage.js
const imageStyle = {
  borderRadius: '50%',
  border: '1px solid #fff',
}

export default function ProfileImage() {
  return <Image src="..." style={imageStyle} />
}

Recuerda que las props requeridas width y height pueden interactuar con tu estilo. Si usas estilos para modificar el ancho de una imagen, también debes establecer su altura en auto para preservar su relación de aspecto intrínseca, o tu imagen se distorsionará.

onLoadingComplete

'use client'

<Image onLoadingComplete={(img) => console.log(img.naturalWidth)} />

Una función de callback que se invoca una vez que la imagen se carga completamente y se ha eliminado el marcador de posición.

La función de callback se llamará con un argumento, una referencia al elemento <img> subyacente.

onLoad

<Image onLoad={(e) => console.log(e.target.naturalWidth)} />

Una función de callback que se invoca cuando la imagen se carga.

El evento de carga puede ocurrir antes de que se elimine el marcador de posición de la imagen y la imagen se decodifique completamente. Si deseas esperar hasta que la imagen se haya cargado por completo, usa onLoadingComplete en su lugar.

onError

<Image onError={(e) => console.error(e.target.id)} />

Una función de callback que se invoca si la imagen falla al cargar.

loading

Recomendación: Esta propiedad solo está destinada para casos de uso avanzado. Cambiar una imagen para cargar con eager normalmente dañará el rendimiento. Recomendamos usar la propiedad priority en su lugar, que precargará la imagen de manera ansiosa.

loading = 'lazy' // {lazy} | {eager}

El comportamiento de carga de la imagen. Por defecto es lazy.

Cuando es lazy, difiere la carga de la imagen hasta que alcanza una distancia calculada desde el viewport.

Cuando es eager, carga la imagen inmediatamente.

Aprende más sobre el atributo loading.

blurDataURL

Una Data URL que se utilizará como imagen de marcador de posición antes de que la imagen src se cargue correctamente. Solo tiene efecto cuando se combina con placeholder="blur".

Debe ser una imagen codificada en base64. Se ampliará y difuminará, por lo que se recomienda una imagen muy pequeña (10px o menos). Incluir imágenes más grandes como marcadores de posición puede afectar el rendimiento de su aplicación.

Pruébelo:

También puede generar una Data URL de color sólido para que coincida con la imagen.

unoptimized

unoptimized = {false} // {false} | {true}

Cuando es true, la imagen fuente se servirá tal cual sin cambiar calidad, tamaño o formato. Por defecto es false.

import Image from 'next/image'

const UnoptimizedImage = (props) => {
  return <Image {...props} unoptimized />
}

Desde Next.js 12.3.0, esta propiedad puede asignarse a todas las imágenes actualizando next.config.js con la siguiente configuración:

next.config.js
module.exports = {
  images: {
    unoptimized: true,
  },
}

Otras Propiedades

Otras propiedades en el componente <Image /> se pasarán al elemento img subyacente, con excepción de las siguientes:

  • srcSet. Utilice Device Sizes en su lugar.
  • decoding. Siempre es "async".

Opciones de Configuración

Además de las propiedades, puede configurar el Componente de Imagen en next.config.js. Las siguientes opciones están disponibles:

remotePatterns

Para proteger su aplicación de usuarios maliciosos, se requiere configuración para usar imágenes externas. Esto asegura que solo imágenes externas de su cuenta puedan servirse desde la API de Optimización de Imágenes de Next.js. Estas imágenes externas pueden configurarse con la propiedad remotePatterns en su archivo next.config.js, como se muestra a continuación:

next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'example.com',
        port: '',
        pathname: '/account123/**',
      },
    ],
  },
}

Nota importante: El ejemplo anterior asegurará que la propiedad src de next/image debe comenzar con https://example.com/account123/. Cualquier otro protocolo, hostname, puerto o ruta no coincidente responderá con 400 Bad Request.

A continuación se muestra otro ejemplo de la propiedad remotePatterns en el archivo next.config.js:

next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: '**.example.com',
      },
    ],
  },
}

Nota importante: El ejemplo anterior asegurará que la propiedad src de next/image debe comenzar con https://img1.example.com o https://me.avatar.example.com o cualquier número de subdominios. Cualquier otro protocolo o hostname no coincidente responderá con 400 Bad Request.

Los patrones comodín pueden usarse tanto para pathname como para hostname y tienen la siguiente sintaxis:

  • * coincide con un solo segmento de ruta o subdominio
  • ** coincide con cualquier número de segmentos de ruta al final o subdominios al principio

La sintaxis ** no funciona en medio del patrón.

domains

Advertencia: Recomendamos configurar remotePatterns estrictos en lugar de domains para proteger su aplicación de usuarios maliciosos. Solo use domains si es dueño de todo el contenido servido desde el dominio.

Similar a remotePatterns, la configuración domains puede usarse para proporcionar una lista de hostnames permitidos para imágenes externas.

Sin embargo, la configuración domains no admite coincidencia de patrones comodín y no puede restringir protocolo, puerto o ruta.

A continuación se muestra un ejemplo de la propiedad domains en el archivo next.config.js:

next.config.js
module.exports = {
  images: {
    domains: ['assets.acme.com'],
  },
}

loaderFile

Si desea usar un proveedor en la nube para optimizar imágenes en lugar de usar la API de Optimización de Imágenes integrada de Next.js, puede configurar loaderFile en su next.config.js de la siguiente manera:

next.config.js
module.exports = {
  images: {
    loader: 'custom',
    loaderFile: './my/image/loader.js',
  },
}

Esto debe apuntar a un archivo relativo a la raíz de su aplicación Next.js. El archivo debe exportar una función predeterminada que devuelva una cadena, por ejemplo:

'use client'

export default function myImageLoader({ src, width, quality }) {
  return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}

Alternativamente, puede usar la propiedad loader para configurar cada instancia de next/image.

Ejemplos:

Avanzado

La siguiente configuración es para casos de uso avanzados y generalmente no es necesaria. Si elige configurar las propiedades a continuación, anulará cualquier cambio a los valores predeterminados de Next.js en futuras actualizaciones.

deviceSizes

Si conoce los anchos de dispositivo esperados de sus usuarios, puede especificar una lista de puntos de interrupción de ancho de dispositivo usando la propiedad deviceSizes en next.config.js. Estos anchos se usan cuando el componente next/image usa la propiedad sizes para asegurar que se sirva la imagen correcta para el dispositivo del usuario.

Si no se proporciona configuración, se usa el siguiente valor predeterminado.

next.config.js
module.exports = {
  images: {
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
  },
}

imageSizes

Puede especificar una lista de anchos de imagen usando la propiedad images.imageSizes en su archivo next.config.js. Estos anchos se concatenan con la matriz de device sizes para formar la matriz completa de tamaños utilizados para generar srcsets de imágenes.

La razón por la que hay dos listas separadas es que imageSizes solo se usa para imágenes que proporcionan una propiedad sizes, lo que indica que la imagen es menor que el ancho completo de la pantalla. Por lo tanto, los tamaños en imageSizes deben ser todos más pequeños que el tamaño más pequeño en deviceSizes.

Si no se proporciona configuración, se usa el siguiente valor predeterminado.

next.config.js
module.exports = {
  images: {
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
  },
}

formats

La API de Optimización de Imágenes predeterminada detectará automáticamente los formatos de imagen admitidos por el navegador a través de la cabecera Accept de la solicitud.

Si la cabecera Accept coincide con más de uno de los formatos configurados, se usa la primera coincidencia en la matriz. Por lo tanto, el orden de la matriz importa. Si no hay coincidencia (o la imagen fuente es animada), la API de Optimización de Imágenes recurrirá al formato original de la imagen.

Si no se proporciona configuración, se usa el siguiente valor predeterminado.

next.config.js
module.exports = {
  images: {
    formats: ['image/webp'],
  },
}

Puede habilitar el soporte AVIF con la siguiente configuración.

next.config.js
module.exports = {
  images: {
    formats: ['image/avif', 'image/webp'],
  },
}

Nota importante:

  • AVIF generalmente tarda un 20% más en codificarse pero se comprime un 20% más en comparación con WebP. Esto significa que la primera vez que se solicita una imagen, generalmente será más lento y luego las solicitudes posteriores que están en caché serán más rápidas.
  • Si aloja usted mismo con un Proxy/CDN delante de Next.js, debe configurar el Proxy para reenviar la cabecera Accept.

Comportamiento de Caché

Lo siguiente describe el algoritmo de caché para el cargador predeterminado. Para todos los demás cargadores, consulte la documentación de su proveedor en la nube.

Las imágenes se optimizan dinámicamente al solicitarse y se almacenan en el directorio <distDir>/cache/images. El archivo de imagen optimizado se servirá para solicitudes posteriores hasta que se alcance la expiración. Cuando se realiza una solicitud que coincide con un archivo en caché pero expirado, la imagen expirada se sirve inmediatamente como obsoleta. Luego, la imagen se optimiza nuevamente en segundo plano (también llamado revalidación) y se guarda en la caché con la nueva fecha de expiración.

El estado de caché de una imagen se puede determinar leyendo el valor de la cabecera de respuesta x-nextjs-cache. Los valores posibles son los siguientes:

  • MISS - la ruta no está en la caché (ocurre como máximo una vez, en la primera visita)
  • STALE - la ruta está en la caché pero excedió el tiempo de revalidación, por lo que se actualizará en segundo plano
  • HIT - la ruta está en la caché y no ha excedido el tiempo de revalidación

La expiración (o más bien Max Age) se define por la configuración minimumCacheTTL o la cabecera Cache-Control de la imagen upstream, lo que sea mayor. Específicamente, se usa el valor max-age de la cabecera Cache-Control. Si se encuentran tanto s-maxage como max-age, se prefiere s-maxage. El max-age también se pasa a cualquier cliente descendente, incluidos CDN y navegadores.

  • Puede configurar minimumCacheTTL para aumentar la duración de la caché cuando la imagen upstream no incluye la cabecera Cache-Control o el valor es muy bajo.
  • Puede configurar deviceSizes y imageSizes para reducir el número total de imágenes generadas posibles.
  • Puede configurar formats para deshabilitar múltiples formatos en favor de un solo formato de imagen.

minimumCacheTTL

Puede configurar el Time to Live (TTL) en segundos para imágenes optimizadas en caché. En muchos casos, es mejor usar una Importación de Imagen Estática que automáticamente hashear los contenidos del archivo y almacenar en caché la imagen para siempre con una cabecera Cache-Control de immutable.

next.config.js
module.exports = {
  images: {
    minimumCacheTTL: 60,
  },
}

La expiración (o más bien Max Age) de la imagen optimizada se define por minimumCacheTTL o la cabecera Cache-Control de la imagen upstream, lo que sea mayor.

Si necesita cambiar el comportamiento de caché por imagen, puede configurar headers para establecer la cabecera Cache-Control en la imagen upstream (por ejemplo, /some-asset.jpg, no /_next/image en sí).

No hay un mecanismo para invalidar la caché en este momento, por lo que es mejor mantener minimumCacheTTL bajo. De lo contrario, puede que necesite cambiar manualmente la propiedad src o eliminar <distDir>/cache/images.

disableStaticImages

El comportamiento predeterminado le permite importar archivos estáticos como import icon from './icon.png' y luego pasarlo a la propiedad src.

En algunos casos, puede que desee deshabilitar esta función si entra en conflicto con otros complementos que esperan que la importación se comporte de manera diferente.

Puede deshabilitar las importaciones de imágenes estáticas dentro de su next.config.js:

next.config.js
module.exports = {
  images: {
    disableStaticImages: true,
  },
}

dangerouslyAllowSVG

El cargador predeterminado no optimiza imágenes SVG por algunas razones. Primero, SVG es un formato vectorial, lo que significa que puede redimensionarse sin pérdida. Segundo, SVG tiene muchas de las mismas características que HTML/CSS, lo que puede llevar a vulnerabilidades sin una Política de Seguridad de Contenido adecuada.

Si necesita servir imágenes SVG con la API de Optimización de Imágenes predeterminada, puede establecer dangerouslyAllowSVG dentro de su next.config.js:

next.config.js
module.exports = {
  images: {
    dangerouslyAllowSVG: true,
    contentDispositionType: 'attachment',
    contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
  },
}

Además, se recomienda encarecidamente establecer también contentDispositionType para forzar al navegador a descargar la imagen, así como contentSecurityPolicy para evitar que los scripts incrustados en la imagen se ejecuten.

Imágenes Animadas

El cargador predeterminado omitirá automáticamente la Optimización de Imágenes para imágenes animadas y servirá la imagen tal cual.

La detección automática de archivos animados es de mejor esfuerzo y admite GIF, APNG y WebP. Si desea omitir explícitamente la Optimización de Imágenes para una imagen animada dada, use la propiedad unoptimized.

Imágenes Responsivas

El srcset generado predeterminado contiene imágenes 1x y 2x para admitir diferentes proporciones de píxeles del dispositivo. Sin embargo, es posible que desee renderizar una imagen responsiva que se estire con el viewport. En ese caso, deberá establecer sizes así como style (o className).

Puede renderizar una imagen responsiva usando uno de los siguientes métodos.

Imagen responsiva usando una importación estática

Si la imagen fuente no es dinámica, puede importarla estáticamente para crear una imagen responsiva:

components/author.js
import Image from 'next/image'
import me from '../photos/me.jpg'

export default function Author() {
  return (
    <Image
      src={me}
      alt="Foto del autor"
      sizes="100vw"
      style={{
        width: '100%',
        height: 'auto',
      }}
    />
  )
}

Pruébelo:

Imagen responsiva con relación de aspecto

Si la imagen fuente es una URL dinámica o remota, también deberá proporcionar width y height para establecer la relación de aspecto correcta de la imagen responsiva:

components/page.js
import Image from 'next/image'

export default function Page({ photoUrl }) {
  return (
    <Image
      src={photoUrl}
      alt="Foto del autor"
      sizes="100vw"
      style={{
        width: '100%',
        height: 'auto',
      }}
      width={500}
      height={300}
    />
  )
}

Pruébelo:

Imagen responsiva con fill

Si no conoce la relación de aspecto, deberá establecer la propiedad fill y establecer position: relative en el elemento padre. Opcionalmente, puede establecer el estilo object-fit según el comportamiento de estiramiento vs recorte deseado:

app/page.js
import Image from 'next/image'

export default function Page({ photoUrl }) {
  return (
    <div style={{ position: 'relative', width: '500px', height: '300px' }}>
      <Image
        src={photoUrl}
        alt="Foto del autor"
        sizes="500px"
        fill
        style={{
          objectFit: 'contain',
        }}
      />
    </div>
  )
}

Pruébelo:

Detección de Tema

Si desea mostrar una imagen diferente para el modo claro y oscuro, puede crear un nuevo componente que envuelva dos componentes <Image> y muestre el correcto basado en una consulta de medios CSS.

components/theme-image.module.css
.imgDark {
  display: none;
}

@media (prefers-color-scheme: dark) {
  .imgLight {
    display: none;
  }
  .imgDark {
    display: unset;
  }
}
import styles from './theme-image.module.css'
import Image, { ImageProps } from 'next/image'

type Props = Omit<ImageProps, 'src' | 'priority' | 'loading'> & {
  srcLight: string
  srcDark: string
}

const ThemeImage = (props: Props) => {
  const { srcLight, srcDark, ...rest } = props

  return (
    <>
      <Image {...rest} src={srcLight} className={styles.imgLight} />
      <Image {...rest} src={srcDark} className={styles.imgDark} />
    </>
  )
}
import styles from './theme-image.module.css'
import Image from 'next/image'

const ThemeImage = (props) => {
  const { srcLight, srcDark, ...rest } = props

  return (
    <>
      <Image {...rest} src={srcLight} className={styles.imgLight} />
      <Image {...rest} src={srcDark} className={styles.imgDark} />
    </>
  )
}

Nota importante: El comportamiento predeterminado de loading="lazy" asegura que solo se cargue la imagen correcta. No puede usar priority o loading="eager" porque eso causaría que ambas imágenes se carguen. En su lugar, puede usar fetchPriority="high".

Pruébelo:

Errores Conocidos en Navegadores

Este componente next/image usa carga diferida nativa del navegador, que puede recurrir a carga inmediata en navegadores anteriores a Safari 15.4. Al usar el marcador de posición con desenfoque, navegadores anteriores a Safari 12 recurrirán a un marcador de posición vacío. Al usar estilos con width/height en auto, es posible causar Cambio de Diseño (Layout Shift) en navegadores anteriores a Safari 15 que no preservan la relación de aspecto. Para más detalles, vea este video de MDN.

  • Safari 15 - 16.3 muestra un borde gris durante la carga. Safari 16.4 solucionó este problema. Posibles soluciones:
    • Usar CSS @supports (font: -apple-system-body) and (-webkit-appearance: none) { img[loading="lazy"] { clip-path: inset(0.6px) } }
    • Usar priority si la imagen está visible inicialmente (above the fold)
  • Firefox 67+ muestra un fondo blanco durante la carga. Posibles soluciones:

Historial de Versiones

VersiónCambios
v13.4.14Soporte para prop placeholder con data:/image...
v13.2.0Se agregó configuración contentDispositionType.
v13.0.6Se agregó prop ref.
v13.0.0La importación next/image se renombró a next/legacy/image. La importación next/future/image se renombró a next/image. Hay un codemod disponible para renombrar sus importaciones de forma segura y automática. Se eliminó el envoltorio <span>. Se eliminaron props layout, objectFit, objectPosition, lazyBoundary, lazyRoot. alt es obligatorio. onLoadingComplete recibe referencia al elemento img. Se eliminó la configuración de loader incorporada.
v12.3.0remotePatterns y configuración unoptimized son estables.
v12.2.0Se agregaron remotePatterns experimental y configuración experimental unoptimized. Se eliminó layout="raw".
v12.1.1Se agregó prop style. Soporte experimental para layout="raw" agregado.
v12.1.0Se agregaron configuraciones dangerouslyAllowSVG y contentSecurityPolicy.
v12.0.9Se agregó prop lazyRoot.
v12.0.0Se agregó configuración formats.
Se agregó soporte AVIF.
Envoltorio <div> cambiado a <span>.
v11.1.0Se agregaron props onLoadingComplete y lazyBoundary.
v11.0.0Soporte para prop src con importación estática.
Se agregó prop placeholder.
Se agregó prop blurDataURL.
v10.0.5Se agregó prop loader.
v10.0.1Se agregó prop layout.
v10.0.0Se introdujo next/image.