Image Optimization
On-demand image resizing and format conversion powered by Sharp. Images are automatically converted to WebP or AVIF, resized to the requested width, cached to disk, and served with proper cache headers. Each framework has its own <Image> component: see the framework-specific Components page for usage.
#How It Works
AbsoluteJS registers a /_absolute/image endpoint automatically when your server starts. When a browser requests an optimized image:
Accept header to determine the best output format (AVIF, WebP, or JPEG)Cache-Control, ETag, and Vary: Accept headers#Configuration
Add an images object to your absolute.config.ts. All fields are optional : the defaults work well for most apps.
// absolute.config.ts : basic image optimization
import { defineConfig } from '@absolutejs/absolute';
export default defineConfig({
reactDirectory: './src/frontend',
images: {
quality: 80,
formats: ['image/webp', 'image/avif']
}
});#All Options
// absolute.config.ts : full image optimization config
import { defineConfig } from '@absolutejs/absolute';
export default defineConfig({
reactDirectory: './src/frontend',
images: {
// Widths used for responsive srcset when layout is "responsive"
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
// Widths used for fixed-size images
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
// Output formats : the server picks the best one the browser supports
formats: ['image/webp', 'image/avif'],
// Minimum cache TTL in seconds for optimized images
minimumCacheTTL: 60,
// Allow remote images from specific origins
remotePatterns: [
{
protocol: 'https',
hostname: 'images.example.com',
port: '',
pathname: '/assets/**'
}
],
// Output quality (1-100)
quality: 80,
// Custom endpoint path (default: '/_absolute/image')
path: '/_absolute/image',
// Disable optimization entirely (serve originals)
unoptimized: false
}
});[640, 750, 828, 1080, 1200, 1920, 2048, 3840][16, 32, 48, 64, 96, 128, 256, 384]["webp"]. Add "avif" for smaller files at slower encode speed.60.75."/_absolute/image".#Optimization Endpoint
The endpoint accepts three query parameters:
deviceSizes or imageSizes values.# The image optimization endpoint accepts these query parameters:
# url : path to the source image (required)
# w : desired width in pixels (required)
# q : quality 1-100 (optional, defaults to config value)
# Fetch a 640px-wide WebP version
curl -H "Accept: image/webp" \
"http://localhost:3000/_absolute/image?url=/images/hero.jpg&w=640&q=80"
# Fetch an AVIF version
curl -H "Accept: image/avif" \
"http://localhost:3000/_absolute/image?url=/images/hero.jpg&w=1200&q=75"
# The server reads the Accept header and returns the best
# supported format. If the browser doesn't support WebP or AVIF,
# the original format is returned at the requested size.#Content Negotiation
The endpoint reads the browser's Accept header to pick the best format. If the browser supports AVIF and it's in your formats config, AVIF is served. Otherwise WebP. Otherwise the source format. The response includes Vary: Accept so CDNs cache each variant separately.
#Caching
Optimized images are cached to disk at {buildDir}/.cache/images/. Each entry is keyed by a SHA-256 hash of the URL, width, quality, and format. Cache files persist across server restarts.
If-None-Match on subsequent requests and get 304 Not Modified.minimumCacheTTL (seconds). After expiry, the next request regenerates the image.public, max-age=<TTL>, must-revalidate.#Remote Images
By default, only local images are allowed. To optimize remote images, configure remotePatterns with the allowed origins. This prevents the endpoint from being used as an open proxy.
// absolute.config.ts : allowing remote images
import { defineConfig } from '@absolutejs/absolute';
export default defineConfig({
reactDirectory: './src/frontend',
images: {
remotePatterns: [
// Allow all images from a specific CDN
{
protocol: 'https',
hostname: 'cdn.example.com'
},
// Allow images from any subdomain of example.com
{
protocol: 'https',
hostname: '*.example.com',
pathname: '/images/**'
},
// Allow a specific path on a specific host
{
protocol: 'https',
hostname: 'storage.googleapis.com',
pathname: '/my-bucket/**'
}
]
}
});"*.example.com" matches cdn.example.com, etc."/photos/**" matches any path starting with /photos/.#AVIF Support
AVIF delivers ~20-30% smaller files than WebP but encoding is ~50x slower. AbsoluteJS handles this with async pre-generation:
- Add
"avif"to yourformatsarray before"webp" - First request: browser gets WebP immediately
- Background: AVIF variant is generated and cached
- Next request from an AVIF-capable browser: served from cache instantly
#Sharp
Sharp is an optional peer dependency that wraps libvips for fast native image processing. Install it with:
bun add sharpIf Sharp is not installed, the optimization endpoint serves images unoptimized (original format and size) with a one-time console warning. This lets you develop without Sharp and add it when you're ready for production optimization.
#Type Reference
type ImageConfig = {
deviceSizes?: number[];
imageSizes?: number[];
formats?: ImageFormat[];
minimumCacheTTL?: number;
remotePatterns?: RemotePattern[];
quality?: number;
path?: string;
unoptimized?: boolean;
};
type ImageFormat = 'image/webp' | 'image/avif';
type RemotePattern = {
protocol?: 'http' | 'https';
hostname: string;
port?: string;
pathname?: string;
};