Images
Optional image optimization with rebaskImage() and <Image>.
Image plugin setup
Install sharp, which the built-in handler uses:
pnpm add sharpAdd rebaskImage() to your Vite plugins:
// vite.config.ts
import { rebaskImage } from "@rebask/core/vite/image"
plugins: [rsc(), react(), rebask(), rebaskImage()]Create rebask.image.ts at the project root:
// rebask.image.ts
import { handleImage } from "@rebask/core/image"
import sharp from "sharp"
export default function handler(request: Request) {
return handleImage(request, sharp)
}Local images are read from public/. Remote URLs must match a remotePatterns entry, and localPatterns can restrict local paths.
Adapters can provide their own image optimization. For example, vercelAdapter() routes /_rebask/image to Vercel's optimizer when rebaskImage() is configured. In that setup, you don't need rebask.image.ts or Sharp.
<Image>
Use width and height for fixed-size images:
import { Image } from "@rebask/core/components/image"
<Image src="/hero.jpg" alt="Storefront" width={1200} height={600} preload />
<Image src="/product.jpg" alt="Product" width={800} height={800} />Add sizes for responsive images. It tells the browser how wide the image will render:
<Image
src="/hero.jpg"
alt="Storefront"
width={1200}
height={600}
sizes="(min-width: 1200px) 1200px, 100vw"
/>Static imports
Import an image and pass it as src. Static imports are optimized through the handler like other
local images, and their dimensions are read at build time, so width and height are not needed:
import hero from "./hero.jpg"
<Image src={hero} alt="Storefront" placeholder="blur" />placeholder="blur" uses sharp to generate the blur at build time. Without sharp, pass
blurDataURL to <Image>.
Static imports are not subject to localPatterns.
Fill
fill makes the image cover a positioned parent. Give the parent dimensions:
<div style={{ position: "relative", width: "100%", aspectRatio: "2 / 1" }}>
<Image
src="/hero.jpg"
alt="Storefront"
fill
sizes="(min-width: 1200px) 1200px, 100vw"
/>
</div><Image> props
| Prop | |
|---|---|
src | Path or URL |
alt | Required |
width / height | Required unless fill |
sizes | Rendered width, used for responsive images |
fill | Fill the positioned parent |
quality | 1–100, snapped to the configured qualities |
preload | Preload the image |
loading | "lazy" | "eager" |
placeholder | "blur" | "empty" | data URL |
blurDataURL | Required with placeholder="blur" |
unoptimized | Skip optimization |
loader | Custom loader |
SVG, data:, and blob: URLs are not optimized. The handler rejects SVG unless
dangerouslyAllowSVG is enabled. Other <img> attributes, such as className, style,
fetchPriority, and onLoad, are passed through.
rebaskImage() options
These are the defaults:
rebaskImage({
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
imageSizes: [32, 48, 64, 96, 128, 256, 384],
path: "/_rebask/image",
qualities: [75],
formats: ["image/webp"],
contentSecurityPolicy: "script-src 'none'; frame-src 'none'; sandbox;",
contentDispositionType: "attachment",
minimumCacheTTL: 14400,
unoptimized: false,
localPatterns: undefined,
remotePatterns: [],
dangerouslyAllowSVG: false,
dangerouslyAllowLocalIP: false,
maximumRedirects: 3,
maximumResponseBody: 50000000, // 50 MB
maximumCacheSize: 50000000, // 50 MB
handler: "rebask.image.ts",
})deviceSizessets the widths used for responsive images.imageSizessets the widths used for fixed-size images.pathsets the endpoint and the URLs generated by<Image>.qualitiessets the allowed quality values. Other values snap to the closest one.formatssets the formats offered to clients that advertise support.contentSecurityPolicysets the CSP header on image responses.contentDispositionTypesetsinlineorattachmenton image responses.minimumCacheTTLsets the minimum cache lifetime for public images. A longer upstreamCache-Controlwins.unoptimizeddisables optimization for all images.localPatternslimits which files underpublic/can be optimized. Leave it undefined to allow all local images.remotePatternslists the remote URLs the server may fetch. No remote images are allowed by default.dangerouslyAllowSVGserves SVG images instead of rejecting them. Only enable it for trusted sources.dangerouslyAllowLocalIPallows remote images from private or loopback addresses. Leave it false to block SSRF.maximumRedirectssets how many redirects a remote image may follow.maximumResponseBodycaps the remote image size in bytes.maximumCacheSizecaps the in-memory image cache in bytes. Caching is disabled in development.handlersets the handler file. Rebask also detectsrebask.image.js.
Image caching
Optimized images are cached in memory in production. The handler follows the upstream Cache-Control header:
no-storeandprivateresponses bypass the shared cache.privateresponses stay private to the browser.no-cacheandmax-age=0responses bypass the shared cache and are returned withmax-age=0, must-revalidate.s-maxageandmax-ageset the cache lifetime, withminimumCacheTTLas the floor for public images with a positive max age.
Remote patterns
Remote images need an entry in remotePatterns:
rebaskImage({
remotePatterns: [
{ hostname: "images.example.com", pathname: "/products/**" },
{ protocol: "https", hostname: "*.cdn.example.com" },
],
})Each pattern can set protocol, hostname, port, pathname, and search. hostname is
required. Patterns match the whole value.
*matches a single segment, such as one subdomain or one path segment.**matches any number of segments.searchmatches the query string exactly, including?. An empty string matches no query string.- When
protocol,port,pathname, orsearchis omitted, any value matches.
localPatterns uses the same pathname and search rules:
rebaskImage({
localPatterns: [
{ pathname: "/images/**" },
{ pathname: "/products/*.jpg", search: "" },
],
})