Mejores prácticas de imágenes e ícones
Un resumen condensado de las 25 mejores prácticas más importantes extraídas de cada página en esta sección.
- Prefiere next/image sobre img: Usa
next/imagepara que Next.js sirva automáticamente WebP/AVIF, cargue de forma diferida las imágenes fuera de pantalla y genere tamaños responsivos. La etiqueta<img>sin procesar no incluye optimización y daña el LCP. - Siempre empareja fill con sizes: Usar
fillsin la propsizeshace que el navegador descargue la variante más grande para cada dispositivo. Proporciona una cadenasizesconsciente de puntos de corte que coincida con tus columnas de diseño reales. - Establece position: relative en padres con fill: El padre de una imagen con
filldebe tenerposition: relative(o absolute/fixed) más dimensiones definidas, o la imagen se colapsa a altura cero. Usa un envoltorio de relación de aspecto para bloquear el diseño. - Reserva priority para imágenes LCP: Solo agrega
prioritya imágenes hero por encima del pliegue (típicamente una o dos por página). El uso excesivo cancela el beneficio de carga diferida denext/image. - Configura remotePatterns explícitamente: Agrega cada host de imagen externo (por ejemplo,
images.unsplash.com,images.pexels.com,cdn.pixabay.com) aimages.remotePatternsennext.config.tsy reinicia el servidor de desarrollo. Las entradas faltantes causan errores 400 en tiempo de ejecución, no en tiempo de compilación. - Prefiere importaciones estáticas para imágenes locales: Las importaciones estáticas devuelven
StaticImageDataconwidth,heighty unblurDataURLgenerado automáticamente, eliminando boilerplate manual. También habilitanplaceholder="blur"sin trabajo extra. - Usa width/height solo para relación de aspecto: Las props
widthyheightdefinen el tamaño solicitado y la relación de aspecto — no redimensionan ni recortan el elemento renderizado. Controla el tamaño visual con clases CSS. - Nunca expongas claves API en el navegador: Las claves de Unsplash, Pexels y Pixabay deben mantenerse en el lado del servidor; busca desde Componentes de Servidor o Manejadores de Ruta y almacena secretos en
.env.local. Pixabay es especialmente arriesgado porque la clave es un parámetro de consulta. - Cachea respuestas API con revalidate: Envuelve búsquedas de fotos de stock con
next: { revalidate: 3600 }para que te mantengas dentro de límites de tasa por hora (Unsplash 50/5000, Pexels 200, Pixabay 100/min) y mantengas las páginas rápidas. Esto también evita sobrecargar las APIs de terceros en cada solicitud. - Usa el formato correcto de encabezado Auth: Unsplash requiere
Authorization: Client-ID <key>, Pexels requiere la clave sin procesar sin prefijoBearer, y Pixabay usa un parámetro de consultakey. Mezclar estos devuelve un 401 y desperdicia tiempo de depuración. - Elige el tamaño de URL correcto: Usa
regular/webformatURL/largepara visualización y reservaraw/original/fullHDURLpara descargas, ya que los originales pueden exceder 10MB. Servir imágenes de tamaño excesivo deshace el punto de un canal de optimización. - Respeta la atribución y el seguimiento de descargas: Unsplash requiere crédito del fotógrafo con parámetros UTM y una llamada a
download_locationcada vez que se usa una foto. Pexels y Pixabay fomentan fuertemente la atribución incluso cuando no es estrictamente requerida. - Trata el texto alt de API como no confiable: Campos como
altde Pexels oalt_descriptionde Unsplash pueden estar vacíos, ser genéricos o nulos. Proporciona un respaldo significativo para mantener las imágenes accesibles. - Nunca hagas hotlink de Pixabay en producción: La licencia de Pixabay permite solo hotlinking temporal de CDN; para producción, descarga y re-aloja imágenes en tu propia infraestructura. Planifica un paso de compilación o canal de ingesta en consecuencia.
- Importa ícones desde subcaminos de familia: Siempre importa
react-iconsdesde una ruta de familia comoreact-icons/fa— importar desde la raíz del paquete puede derrotar el tree-shaking y agrupar miles de ícones sin usar. La misma disciplina se aplica a cualquier importación de ícones de estilo barrel. - Estiliza Heroicons solo con className: Heroicons ignoran las props
sizeycolor; establece dimensiones y color a través de utilidades de Tailwind comoh-6 w-6 text-blue-500. Alias imports cuando uses variantes outline y solid del mismo ícono en un archivo. - Tipifica ícones como componentes, no elementos: Usa
LucideIcon,IconType, oReact.ComponentType<SVGProps<SVGSVGElement>>para tipificar props de ícones para que puedas renderizarlos con<Icon size={…} />. Pasar un elemento renderizado en lugar de un tipo de componente rompe los botones envolventes reutilizables. - Marca proveedores IconContext como Client:
IconContext.Providerdereact-iconsusa React Context y debe vivir en un Componente Cliente en el App Router. Colócalo lo suficientemente alto en el árbol para cubrir el subárbol que deseas estilizar. - Usa currentColor para SVGs personalizados: Establece
stroke="currentColor"(ofill="currentColor") en ícones SVG en línea para que hereden color a través de clases padretext-*. Esto hace que un conjunto de ícones hecho a mano se comporte como Lucide o Heroicons. - Haz la accesibilidad de SVG explícita: Los ícones decorativos deben tener
aria-hidden="true"y sinrole; los ícones informativos necesitanrole="img"más unaria-label. También escribe atributos SVG en camelCase (viewBox,strokeWidth) y manténviewBoxincluso después de la optimización de SVGO. - Establece intencionalmente los valores predeterminados de fill y stroke: SVG establece por defecto
fillystrokea negro, así que los ícones basados en stroke necesitanfill="none"e ícones rellenos necesitanstroke="none"para evitar renderización sorpresa. El comportamiento solo stroke de Lucide es un ejemplo concreto —fillno tiene efecto allí. - Genera blurDataURLs en tiempo de compilación: Produce BlurHash o pequeños JPEG
blurDataURLs (alrededor de 8x8 píxeles) con anticipación y cachéalos con tus metadatos de imagen. Generarlos por solicitud consharpañade latencia y no puede ejecutarse en el Edge Runtime. - Coincide las dimensiones del esqueleto con el contenido final: Los esqueletos shimmer o de relación de aspecto deben usar la misma relación de aspecto que la imagen cargada para que el diseño no cambie (CLS). Aplica CSS
blur()solo a placeholders diminutos, nunca a imágenes de resolución completa. - Sigue las convenciones de archivos de metadatos de Next.js: Coloca
favicon.icoen la raíz deapp/, y sueltaicon.*,apple-icon.*,opengraph-image.*ytwitter-image.*en los segmentos de ruta donde deben aplicarse. Next.js los conecta en<head>automáticamente y alcanza las imágenes OG por ruta. - Diseña imágenes OG considerando los límites de Satori:
ImageResponsedenext/ogusa Satori, que soporta solo flexbox (sin grid), sinbackground-image: url(), y requiere fuentes cargadas comoArrayBuffer. Apunta a 1200x630, exporta unalt, y prefiereruntime = "edge"para imágenes rápidas y cacheables por página.