Saltar al contenido

API de Servicio de Imágenes

astro:assets fue diseñado para facilitar que cualquier servicio de optimización de imágenes construya un servicio sobre Astro.

Astro proporciona dos tipos de image services: Local y External.

  • Los servicios locales manejan las transformaciones de imágenes directamente en el build para sitios estáticos, o en runtime tanto en modo desarrollo como para renderizado on-demand. Estos son a menudo wrappers alrededor de librerías como Sharp, ImageMagick, o Squoosh. En modo dev y en rutas de producción renderizadas on-demand, los servicios locales usan un API endpoint para hacer la transformación.
  • Los servicios externos apuntan a URLs y pueden añadir soporte para servicios como Cloudinary, ImageKit, Vercel, o cualquier servidor compatible con RIAPI.

Las definiciones de servicio toman la forma de un objeto exportado por defecto con varios métodos obligatorios (“hooks”).

Los servicios externos proporcionan un getURL() que apunta al src de la etiqueta <img> de salida.

Los servicios locales proporcionan un método transform() para realizar transformaciones en tu imagen, y métodos getURL() y parseURL() para usar un endpoint en modo dev y cuando se renderiza on-demand.

Ambos tipos de servicios pueden proporcionar getHTMLAttributes() para determinar los otros atributos del <img> de salida y validateOptions() para validar y aumentar las opciones pasadas.

Un servicio externo apunta a una URL remota para ser usada como el atributo src de la etiqueta <img> final. Esta URL remota es responsable de descargar, transformar y devolver la imagen.

import type { ExternalImageService, ImageTransform, AstroConfig } from "astro";
const service: ExternalImageService = {
validateOptions(options: ImageTransform, imageConfig: AstroConfig['image']) {
const serviceConfig = imageConfig.service.config;
// Enforce the user set max width.
if (options.width && options.width > serviceConfig.maxWidth) {
console.warn(`Image width ${options.width} exceeds max width ${serviceConfig.maxWidth}. Falling back to max width.`);
options.width = serviceConfig.maxWidth;
}
return options;
},
getURL(options, imageConfig) {
return `https://mysupercdn.com/${options.src}?q=${options.quality}&w=${options.width}&h=${options.height}`;
},
getHTMLAttributes(options, imageConfig) {
const { src, format, quality, ...attributes } = options;
return {
...attributes,
loading: options.loading ?? 'lazy',
decoding: options.decoding ?? 'async',
};
}
};
export default service;

Para crear tu propio servicio local, puedes apuntar al endpoint integrado (/_image), o puedes además crear tu propio endpoint que puede llamar a los métodos del servicio.

import type { ImageTransform, LocalImageService, AstroConfig } from "astro";
const service: LocalImageService<AstroConfig["image"]> = {
getURL(options: ImageTransform, imageConfig) {
const searchParams = new URLSearchParams();
searchParams.append('href', typeof options.src === "string" ? options.src : options.src.src);
options.width && searchParams.append('w', options.width.toString());
options.height && searchParams.append('h', options.height.toString());
options.quality && searchParams.append('q', options.quality.toString());
options.format && searchParams.append('f', options.format);
return `/my_custom_endpoint_that_transforms_images?${searchParams}`;
// Or use the built-in endpoint, which will call your parseURL and transform functions:
// return `/_image?${searchParams}`;
},
parseURL(url: URL, imageConfig) {
const params = url.searchParams;
return {
src: params.get('href')!,
width: params.has('w') ? parseInt(params.get('w')!) : undefined,
height: params.has('h') ? parseInt(params.get('h')!) : undefined,
format: params.get('f'),
quality: params.get('q'),
};
},
async transform(inputBuffer: Uint8Array, options: { src: string, [key: string]: any }, imageConfig) {
const { buffer } = await mySuperLibraryThatEncodesImages(options);
return {
data: buffer,
format: options.format,
};
},
getHTMLAttributes(options, imageConfig) {
let targetWidth = options.width;
let targetHeight = options.height;
if (typeof options.src === "object") {
const aspectRatio = options.src.width / options.src.height;
if (targetHeight && !targetWidth) {
targetWidth = Math.round(targetHeight * aspectRatio);
} else if (targetWidth && !targetHeight) {
targetHeight = Math.round(targetWidth / aspectRatio);
}
}
const { src, width, height, format, quality, ...attributes } = options;
return {
...attributes,
width: targetWidth,
height: targetHeight,
loading: attributes.loading ?? 'lazy',
decoding: attributes.decoding ?? 'async',
};
},
propertiesToHash: ['src', 'width', 'height', 'format', 'quality'],
};
export default service;

En el build time para sitios estáticos y rutas prerenderizadas, tanto <Image /> como getImage(options) llaman a la función transform(). Pasan opciones a través de atributos del componente o un argumento options, respectivamente. Las imágenes transformadas se construirán en una carpeta dist/_astro. Sus nombres de archivo contendrán un hash de las propiedades pasadas a propertiesToHash. Esta propiedad es opcional y por defecto será ['src', 'width', 'height', 'format', 'quality']. Si tu image service personalizado tiene más opciones que cambian las imágenes generadas, añádelas al array.

En modo dev y cuando se usa un adapter para renderizar on-demand, Astro no sabe por adelantado qué imágenes necesitan ser optimizadas. Astro usa un GET endpoint (por defecto, /_image) para procesar las imágenes en runtime. <Image /> y getImage() pasan sus opciones a getURL(), que devolverá la URL del endpoint. Luego, el endpoint llama a parseURL() y pasa las propiedades resultantes a transform().

Si implementas tu propio endpoint como un endpoint de Astro, puedes usar getConfiguredImageService e imageConfig para llamar a los métodos parseURL y transform de tu servicio y proporcionar la configuración de imagen.

Para acceder a la configuración del image service (image.service.config), puedes usar imageConfig.service.config.

src/api/my_custom_endpoint_that_transforms_images.ts
import type { APIRoute } from "astro";
import { getConfiguredImageService, imageConfig } from 'astro:assets';
export const GET: APIRoute = async ({ request }) => {
const imageService = await getConfiguredImageService();
const imageTransform = imageService.parseURL(new URL(request.url), imageConfig);
// ... fetch the image from imageTransform.src and store it in inputBuffer
const { data, format } = await imageService.transform(inputBuffer, imageTransform, imageConfig);
return new Response(data, {
status: 200,
headers: {
'Content-Type': mime.getType(format) || ''
}
}
);
}

Consulta el endpoint integrado para un ejemplo completo.

Type: (options: ImageTransform, imageConfig: AstroConfig[‘image’]) => string | Promise<string>

Añadido en: astro@2.1.0

Obligatorio para servicios locales y externos

Para servicios locales, este hook devuelve la URL del endpoint que genera tu imagen (para renderizado on-demand y en modo dev). No se usa durante el build. El endpoint local al que apunta getURL() puede llamar tanto a parseURL() como a transform().

Para servicios externos, este hook devuelve la URL final de la imagen.

Para ambos tipos de servicios, options son las propiedades pasadas por el usuario como atributos del componente <Image /> o como opciones a getImage().

Type: (url: URL, imageConfig: AstroConfig[‘image’]) => { src: string, [key: string]: any } | undefined | Promise<{ src: string, [key: string]: any }> | Promise<undefined>

Añadido en: astro@2.1.0

Obligatorio solo para servicios locales; no disponible para servicios externos

Este hook parsea las URLs generadas por getURL() de vuelta a un objeto con las diferentes propiedades a ser usadas por transform (para renderizado on-demand y en modo dev). No se usa durante el build.

Type: (inputBuffer: Uint8Array, options: { src: string, [key: string]: any }, imageConfig: AstroConfig[‘image’]) => Promise<{ data: Uint8Array; format: ImageOutputFormat }>

Añadido en: astro@2.1.0

Obligatorio solo para servicios locales; no disponible para servicios externos

Este hook transforma y devuelve la imagen y es llamado durante el build para crear los archivos de asset finales.

Debes devolver un format para asegurar que el tipo MIME apropiado se sirva a los usuarios para renderizado on-demand y modo desarrollo.

Type: (options: ImageTransform, imageConfig: AstroConfig[‘image’] ) => Record<string, any> | Promise<Record<string, any>>

Añadido en: astro@2.1.0

Opcional para servicios locales y externos

Este hook devuelve todos los atributos adicionales usados para renderizar la imagen como HTML, basándose en los parámetros pasados por el usuario (options).

Type: (options: ImageTransform, imageConfig: AstroConfig[‘image’] ) => UnresolvedSrcSetValue[] | Promise<UnresolvedSrcSetValue[]>

Añadido en: astro@3.3.0

Opcional para servicios locales y externos.

Este hook genera múltiples variantes de la imagen especificada, por ejemplo, para generar un atributo srcset en un <img> o en el source de un <picture>.

Este hook devuelve un array de objetos con las siguientes propiedades:

export type UnresolvedSrcSetValue = {
transform: ImageTransform;
descriptor?: string;
attributes?: Record<string, any>;
};

Type: (options: ImageTransform, imageConfig: AstroConfig[‘image’] ) => ImageTransform | Promise<ImageTransform>

Añadido en: astro@2.1.4

Opcional para servicios locales y externos

Este hook te permite validar y aumentar las opciones pasadas por el usuario. Esto es útil para establecer opciones por defecto, o decirle al usuario que un parámetro es obligatorio.

Mira cómo se usa validateOptions() en los servicios integrados de Astro.

Type: (url: string, imageConfig: AstroConfig[‘image’] ) => Omit<ImageMetadata, ‘src’ | ‘fsPath’> | Promise<Omit<ImageMetadata, ‘src’ | ‘fsPath’>>

Añadido en: astro@6.0.0

Opcional para servicios locales y externos

Este hook te permite extender el comportamiento de inferRemoteSize(). Esto es útil para reducir el tráfico de red cacheando imágenes, o cuando puedes predecir la información de la imagen desde la URL de la imagen.

Configura el image service a usar en astro.config.mjs. La config toma la siguiente forma:

astro.config.mjs
import { defineConfig } from "astro/config";
export default defineConfig({
image: {
service: {
entrypoint: "your-entrypoint", // 'astro/assets/services/sharp' | string,
config: {
// ... service-specific config. Optional.
}
}
},
});

Añadido en: astro@5.16.6

Si tu image service soporta props adicionales en el componente <Image> de Astro, el componente <Picture>, o la función getImage(), puedes añadir tipos para estos extendiendo la interfaz Astro.CustomImageProps.

Por ejemplo, para añadir una prop personalizada blur que tu image service soporta:

declare namespace Astro {
interface CustomImageProps {
/** Apply a Gaussian blur with this radius to the image. */
blur?: number;
}
}

Puedes exponer estos tipos a los usuarios haciendo que tu image service sea una integración de Astro y usando el helper injectTypes().

Luego, los usuarios podrán obtener autocompletado y type safety para tus props personalizadas:

<Image blur="yes" src={myPhoto} />
// ^^^^^^^^^^
// Type 'string' is not assignable to type 'number | undefined'.
Contribuir Comunidad Patrocinar