Docs / Módulo / Imágenes
Módulo de Imágenes
CDN y API para redimensionado, compresión y conversión (WebP / AVIF) con baja latencia en LatAm y caché integrada. Soporta tres modos de integración: URL directa, librería JavaScript con lazy loading, y API autenticada.
Introducción
Las imágenes representan más del 50 % del peso de una página web. El módulo de Imágenes de Webability las procesa, redimensiona y convierte a WebP o AVIF en tiempo real, con caché integrada. Solo necesitas tu clientid (10 letras minúsculas) disponible en la consola de administración.
Ideal para
- • Web y móviles
- • E-commerce y catálogos
- • Mejora de Core Web Vitals
Formatos de salida
WebP y AVIF (o JPG como fallback automático). Entrada: JPG, PNG, GIF, WebP, AVIF.
Modos de integración
- 1. URL directa en HTML
- 2. Lazy Loading JS
- 3. API autenticada
Quickstart
Tres formas de integrar Webability Images, de la más rápida a la más manual.
Optimización rápida
Más fácilNecesitas estar conectado para obtener tu código personalizado
Para ver aquí directamente el script tag con tu ID de cliente y poder descargar tu archivo wa-sw.js personalizado (service worker), primero tienes que iniciar sesión o crear una cuenta. Es gratis y sólo tarda un minuto.
Lazy loading — recomendado para SEO
RecomendadoPara sacar el máximo provecho, cambia tus tags <img> para que incluyan los atributos data-src, data-width, data-height y la clase wa-lazy (o wa-eager para imágenes del primer fold). Con eso, las imágenes entran en el esquema de carga diferida: el script sólo descarga y muestra cada imagen cuando entra en el área visible de la pantalla del usuario.
Antes — tag <img> normal
<img src="/productos/zapatilla.jpg" width="400" height="300" alt="Zapatilla" />
Después — con lazy loading Webability
<img class="wa-lazy" data-src="/productos/zapatilla.jpg" data-width="400" data-height="300" alt="Zapatilla" />
Atributos disponibles
| Atributo | Requerido | Descripción |
|---|---|---|
| class="wa-lazy" | Sí* | Activa el lazy loading: la imagen se carga al entrar en el viewport. Usar en imágenes fuera del primer fold. |
| class="wa-eager" | Sí* | Activa la carga inmediata (eager). Usar en imágenes visibles en el primer fold (hero, logo, LCP). |
| data-src | Sí | Ruta de la imagen original (URL absoluta o relativa al dominio configurado). |
| data-width | Sí | Ancho deseado en píxeles. La imagen se redimensiona a este valor. |
| data-height | Sí | Alto deseado en píxeles. |
* Se debe usar exactamente una de las dos clases en cada <img>. |
||
⚠️ Importante: no uses wa-lazy en imágenes del primer fold
Google penaliza en sus Core Web Vitals el uso de lazy loading en la imagen principal de la página (el LCP — Largest Contentful Paint).
Si la imagen hero, el logo destacado o cualquier imagen visible sin scroll usa wa-lazy, el navegador retrasará su carga y tu
puntuación de PageSpeed / Lighthouse caerá.
La regla es simple: primer fold = wa-eager, resto de la página = wa-lazy.
✗ Incorrecto (penaliza LCP)
<!-- Hero visible sin scroll --> <img class="wa-lazy" data-src="/hero.jpg" data-width="1200" />
✓ Correcto (favorece LCP)
<!-- Hero visible sin scroll --> <img class="wa-eager" data-src="/hero.jpg" data-width="1200" />
¿Por qué Google y SEO lo recomiendan?
El lazy loading reduce drásticamente el peso inicial de la página: las imágenes fuera de pantalla no se descargan hasta que el usuario llega a ellas. Esto mejora directamente el LCP (Largest Contentful Paint) y el TBT (Total Blocking Time), dos métricas clave de Core Web Vitals que Google usa para el ranking de búsqueda. Además, reduce el consumo de ancho de banda, especialmente en móviles con conexiones lentas.
Y hay una ventaja extra: si en algún momento tu cuenta Webability dejara de estar activa, tu sitio no se rompe. El script simplemente carga las imágenes originales con lazy loading normal — tus visitantes ven las imágenes de todas formas, sin errores ni espacios vacíos.
URLs directas en el CDN
No recomendadoTambién puedes construir la URL de una imagen procesada directamente y usarla en el atributo src. La estructura es:
Estructura de URL directa
https://cdn.webability.info/[clientid]/ruta/en/tu/cdn/720x480/imagen.jpg.webp
clientid — tu ID de cliente (10 letras) · ruta — directorio en tu CDN de origen · WxH — dimensiones en píxeles · archivo — nombre del archivo original · formato — webp, avif o jpg
Ejemplo
<img src="https://cdn.webability.info/abcdefghij/imagenes/720x480/portada.jpg.webp" alt="Portada">
⚠️ Por qué preferimos el lazy loading automático (100×)
Las URLs directas funcionan, pero tienen un problema grave: si tu cuenta Webability dejara de estar activa por cualquier razón, todas las imágenes de tu sitio mostrarían un error. Los visitantes verían espacios vacíos o íconos rotos.
Con el lazy loading automático del paso 2, esto nunca ocurre: si el servicio no está disponible, el script carga las imágenes originales de tu servidor de forma transparente, sin errores y sin que tus visitantes noten nada. Tu sitio siempre funciona.
Además, el lazy loading optimiza automáticamente el formato según el navegador, redimensiona según las dimensiones que indiques y sólo descarga cada imagen cuando es necesaria. Las URLs directas requieren que construyas y mantengas cada URL a mano.
Llamada directa por URL
El método más simple: construye la URL de la imagen optimizada y úsala directamente en el atributo src de cualquier etiqueta <img>, en CSS, en etiquetas <picture> o como argumento de cualquier petición HTTP. No requiere JavaScript ni autenticación.
Estructura de la URL
https://cdn.webability.info/{clientid}/{ruta}/{WxH}/{archivo.ext}
| Segmento | Descripción |
|---|---|
| {clientid} | Tu identificador de cliente (10 letras minúsculas). Disponible en la consola → Configuración. |
| {ruta} | Directorio de la imagen en tu CDN de origen, sin el dominio. Puede contener subcarpetas. |
| {WxH} | Dimensiones objetivo en píxeles. Formato: anchoXalto, p. ej. 800x600. |
| {archivo.ext} | Nombre del archivo original incluyendo su extensión, seguido de .webp, .avif o .jpg para la salida deseada. |
Ejemplos
Etiqueta <img> simple
<img src="https://cdn.webability.info/abcdefghij/productos/800x600/zapatilla.jpg.webp" alt="Zapatilla deportiva" width="800" height="600" />
Elemento <picture> con AVIF y WebP
<picture> <source type="image/avif" srcset="https://cdn.webability.info/abcdefghij/blog/1200x630/portada.jpg.avif" /> <source type="image/webp" srcset="https://cdn.webability.info/abcdefghij/blog/1200x630/portada.jpg.webp" /> <img src="https://cdn.webability.info/abcdefghij/blog/1200x630/portada.jpg.jpg" alt="Portada del artículo" width="1200" height="630" /> </picture>
srcset responsivo
<img srcset=" https://cdn.webability.info/abcdefghij/hero/480x320/banner.jpg.webp 480w, https://cdn.webability.info/abcdefghij/hero/768x512/banner.jpg.webp 768w, https://cdn.webability.info/abcdefghij/hero/1200x800/banner.jpg.webp 1200w " sizes="(max-width: 600px) 480px, (max-width: 900px) 768px, 1200px" src="https://cdn.webability.info/abcdefghij/hero/1200x800/banner.jpg.webp" alt="Banner principal" />
Imagen de fondo en CSS
.hero {
background-image: url(
"https://cdn.webability.info/abcdefghij/home/1920x1080/fondo.jpg.webp"
);
background-size: cover;
}
cURL — descarga directa
curl -L "https://cdn.webability.info/abcdefghij/productos/400x400/item.png.avif" -o item.avif
Imagen de demostración del sitio (1.6 MB original → ~32 KB en WebP 600×450)
<img src="https://cdn.webability.info/webability/static/600x450/images.png.webp" />
La primera solicitud genera y cachea la imagen. Las siguientes son servidas directamente desde caché con Cache-Control: public, max-age=31536000.
Lazy Loading con la librería JavaScript
RecomendadoIncluye en tu sitio la librería JavaScript personalizada. Detectará automáticamente todos los elementos marcados, construirá las URLs correctas y los cargará de forma diferida (lazy loading), mejorando los Core Web Vitals y el SEO. Si el navegador no soporta WebP o AVIF, servirá automáticamente la alternativa en JPG.
Paso 1 — Incluir la librería en el <head>
<head>
...
<!-- Librería de imágenes Webability (reemplaza {clientid} con tu ID) -->
<script src="https://cdn.webability.info/js/[IDCliente]" defer></script>
...
</head>
Paso 2 — Marcar las imágenes con atributos data-*
En lugar del atributo src, usa los atributos de datos siguientes:
| Atributo | Obligatorio | Descripción |
|---|---|---|
| data-src | Sí | Ruta completa de la imagen en tu CDN de origen (URL absoluta o ruta relativa al dominio configurado). |
| data-width | Sí | Ancho deseado en píxeles (número entero). |
| data-height | Sí | Alto deseado en píxeles (número entero). |
| data-format | No | Formato de salida: webp (defecto), avif, jpg u original (mantiene el formato fuente). |
Ejemplos
Imagen básica en WebP (formato por defecto)
<img class="wa-lazy" data-src="/imagenes/logo.png" data-width="50" data-height="50" style="width:50px; height:50px;" alt="Logo" />
Imagen en AVIF con dimensiones explícitas
<img class="wa-lazy" data-src="/fotos/producto.jpg" data-width="400" data-height="300" data-format="avif" style="width:400px; height:300px;" alt="Producto" />
Hero banner en WebP
<img class="wa-lazy" data-src="/static/images.png" data-width="600" data-height="450" data-format="webp" style="width:600px;" alt="Hero" />
Formato original (sin conversión)
<img class="wa-lazy" data-src="/catalogos/ficha.gif" data-width="300" data-height="200" data-format="original" alt="Animación de ficha" />
Página completa — ejemplo de integración
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Mi Sitio</title>
<script src="https://cdn.webability.info/js/abcdefghij" defer></script>
</head>
<body>
<!-- Logo en header -->
<img class="wa-lazy" data-src="/static/logotr.png" data-width="50" data-height="50" style="width:50px;">
<!-- Galería de productos -->
<img class="wa-lazy" data-src="/productos/camisa-azul.jpg" data-width="400" data-height="400" data-format="webp">
<img class="wa-lazy" data-src="/productos/pantalon.jpg" data-width="400" data-height="400" data-format="avif">
<!-- Indicador de carga (opcional) -->
<div class="wa-loader"></div>
</body>
</html>
URL generada automáticamente por la librería (lo que termina en el src)
https://cdn.webability.info/abcdefghij/productos/400x400/camisa-azul.jpg.webp
La librería solo carga imágenes cuando entran al viewport del usuario (Intersection Observer API), reduciendo el ancho de banda inicial y mejorando el LCP.
API autenticada
La API autenticada permite operaciones avanzadas desde tu backend: obtener imágenes procesadas, subir originales directamente y gestionar la caché. Todos los endpoints requieren los tres headers de autenticación descritos en la sección Autenticación.
Endpoint /v1/image
Gestión completa de imágenes: obtener, subir y purgar caché.
Recupera una imagen procesada y redimensionada. Si no existe en caché, la descarga desde tu CDN de origen, la convierte y la almacena. La respuesta es el binario de la imagen con el Content-Type correspondiente.
Segmentos de la URL
| Segmento | Descripción |
|---|---|
| {ruta} | Directorio de la imagen en el repositorio del cliente. |
| {WxH} | Dimensiones en píxeles. Formato: anchoXalto, p. ej. 800x600. |
| {archivo.ext} | Nombre del archivo original con su extensión fuente, más la extensión de salida: imagen.jpg.webp. Salida soportada: webp, avif, jpg. |
Ejemplos de request
cURL — obtener imagen
curl -X GET \
-H "X-WA-Token: {token}" \
-H "X-WA-Timestamp: {unix}" \
-H "X-WA-Digest: {hmac}" \
"https://api.webability.info/v1/image/productos/800x600/zapatilla.jpg.webp" \
-o zapatilla.webp
Go — HTTP client
req, _ := http.NewRequest("GET",
"https://api.webability.info/v1/image/productos/800x600/zapatilla.jpg.webp", nil)
req.Header.Set("X-WA-Token", token)
req.Header.Set("X-WA-Timestamp", ts)
req.Header.Set("X-WA-Digest", digest)
resp, _ := http.DefaultClient.Do(req)
// resp.Body contiene la imagen binaria
Respuesta
HTTP/1.1 200 OK Content-Type: image/webp Cache-Control: public, max-age=31536000 [binary image data]
Sube una imagen original al repositorio del cliente. Acepta los formatos jpg, jpeg, png, gif, webp y avif. Tamaño máximo: 50 MB. Al subir un archivo, purga automáticamente todas las versiones cacheadas del mismo.
Nota:
El tamaño máximo se puede cambiar en las cuentas empresariales.
Body
Content-Type: multipart/form-data con el campo file conteniendo el binario de la imagen.
cURL — subir imagen
curl -X POST \
-H "X-WA-Token: {token}" \
-H "X-WA-Timestamp: {unix}" \
-H "X-WA-Digest: {hmac}" \
-F "file=@/local/zapatilla.jpg" \
"https://api.webability.info/v1/image/productos/zapatilla.jpg"
Respuesta JSON
{
"status": "ok",
"path": "productos/zapatilla.jpg",
"filename": "zapatilla.jpg",
"size": 284560,
"cache_purged": 12
}
Permite tres modos de eliminación:
| URL | Efecto |
|---|---|
| /v1/image | Purga toda la caché de versiones procesadas (secondcache). Los originales se conservan. |
| /v1/image/prod/img.jpg | Elimina el original y todas sus versiones cacheadas. |
| /v1/image/carpeta/ | Elimina la carpeta completa de ambas cachés (originales y versiones procesadas). |
cURL — purgar imagen específica
curl -X DELETE \
-H "X-WA-Token: {token}" \
-H "X-WA-Timestamp: {unix}" \
-H "X-WA-Digest: {hmac}" \
"https://api.webability.info/v1/image/productos/zapatilla.jpg"
Respuesta JSON
{
"status": "ok",
"deleted_firstcache": 1,
"deleted_secondcache": 8,
"total": 9
}
Endpoint /v1/stat
Estadísticas de uso del repositorio y la caché del cliente. Solo soporta GET.
Devuelve el total de archivos y tamaño por caché y por formato.
Request
curl -X GET \
-H "X-WA-Token: {token}" \
-H "X-WA-Timestamp: {unix}" \
-H "X-WA-Digest: {hmac}" \
"https://api.webability.info/v1/stat"
Respuesta JSON
{
"status": "ok",
"client": "abcdefghij",
"firstcache": {
"files": 120,
"size_bytes": 48234560,
"size_mb": 46.01,
"by_format": { "jpg": 80, "png": 30, "gif": 10 }
},
"secondcache": {
"files": 850,
"size_bytes": 210345678,
"size_mb": 200.61,
"by_format": { "webp": 600, "avif": 150, "jpg": 100 }
},
"total": {
"files": 970,
"size_bytes": 258580238,
"size_mb": 246.62
}
}
Lista todas las versiones cacheadas de una imagen específica con sus dimensiones, formato y tamaño.
Request
curl -X GET \
-H "X-WA-Token: {token}" \
-H "X-WA-Timestamp: {unix}" \
-H "X-WA-Digest: {hmac}" \
"https://api.webability.info/v1/stat/banners/logo.jpg"
Respuesta JSON
{
"status": "ok",
"image": "banners/logo.jpg",
"original": {
"exists": true,
"size_bytes": 142560
},
"versions": [
{
"filename": "800x600-logo.webp",
"size": 18432,
"width": 800,
"height": 600,
"format": "webp"
},
{
"filename": "400x300-logo.webp",
"size": 9216,
"width": 400,
"height": 300,
"format": "webp"
}
],
"version_count": 2
}
Autenticación
Todos los endpoints de la API autenticada requieren tres headers en cada request. El digest es un HMAC-SHA256 calculado con tu token como clave secreta.
| Header | Valor |
|---|---|
| X-WA-Token | Tu token de cuenta, disponible en la consola de administración. |
| X-WA-Timestamp | Unix timestamp actual en segundos. Debe estar dentro de ±5 minutos del reloj del servidor. |
| X-WA-Digest | HMAC-SHA256 en hexadecimal. Mensaje canónico: {METHOD}|{PATH}|{TIMESTAMP}|{TOKEN}. Clave: tu token. |
Ejemplo de cálculo del digest
Go
import (
"crypto/hmac"
"crypto/sha256"
"fmt"
"time"
)
token := "mi_token_secreto"
method := "GET"
path := "/v1/image/productos/800x600/item.jpg.webp"
ts := fmt.Sprintf("%d", time.Now().Unix())
msg := method + "|" + path + "|" + ts + "|" + token
mac := hmac.New(sha256.New, []byte(token))
mac.Write([]byte(msg))
digest := fmt.Sprintf("%x", mac.Sum(nil))
JavaScript (Node.js)
const crypto = require('crypto');
const token = 'mi_token_secreto';
const method = 'GET';
const path = '/v1/image/productos/800x600/item.jpg.webp';
const ts = Math.floor(Date.now() / 1000).toString();
const msg = `${method}|${path}|${ts}|${token}`;
const digest = crypto
.createHmac('sha256', token)
.update(msg)
.digest('hex');
PHP
$token = 'mi_token_secreto';
$method = 'GET';
$path = '/v1/image/productos/800x600/item.jpg.webp';
$ts = (string) time();
$msg = "$method|$path|$ts|$token";
$digest = hash_hmac('sha256', $msg, $token);
Códigos de error
Los errores de la API devuelven un JSON con status, code y message.
Formato de error
{ "status": "error", "code": 2010, "message": "Imagen original no encontrada" }
| HTTP | Código | Descripción |
|---|---|---|
| 401 | 2001 | Headers de autenticación faltantes o inválidos. |
| 401 | 2002 | Firma HMAC inválida o timestamp fuera de rango (±5 min). |
| 401 | 2003 | Token no encontrado. |
| 400 | 2004 | El cliente no tiene configuración CDN activa. |
| 400 | 2010 | URL inválida (segmentos insuficientes) o imagen original no encontrada en el CDN de origen. |
| 400 | 2011 | Falta la extensión del archivo de salida. |
| 400 | 2012 | Formato de dimensiones inválido. Se espera WxH, p. ej. 800x600. |
| 400 | 2013 | Formato de salida no soportado. Usa webp, avif o jpg. |
| 400 | 2020 | Subida: falta el campo file en el formulario multipart. |
| 400 | 2021 | Subida: formato de archivo no permitido. |
| 403 | 2022 | Subida: path traversal detectado. |
| 400 | 2023 | Subida: error al guardar el archivo en el servidor. |
| 403 | 2030 | Eliminación: path traversal detectado. |
| 400 | 2031 | Eliminación: error durante la operación de borrado. |