The Image component provides optimized image loading with Cloudflare Image transformations, automatic srcset generation, lazy loading strategies, blur placeholders, and dark mode support.
The Image component requires src, alt, width, and height props. It automatically generates optimized srcset for responsive images.
<Image
src="/images/hero.jpg"
alt="Hero image"
width={800}
height={600}
/>Use the placeholder prop to show a blurred low-quality image while the full image loads. This provides a better user experience for slower connections.
<Image
src="/images/photo.jpg"
alt="Photo with blur placeholder"
width={400}
height={300}
placeholder="blur"
/>Control when images load with different loading strategies:
eager - Load immediately (above-the-fold content)
lazy - Native lazy loading with 100px root margin (default)
lazy-near - Load when within 200px of viewport
lazy-visible - Load only when visible (0px margin)
idle - Load during browser idle time
// Above-the-fold hero image
<Image
src="/images/hero.jpg"
alt="Hero"
width={1920}
height={1080}
loading="eager"
fetchpriority="high"
/>
// Below-the-fold content
<Image
src="/images/gallery.jpg"
alt="Gallery"
width={800}
height={600}
loading="lazy-near"
/>Provide a srcDark prop to automatically switch images based on system color scheme preference.
<Image
src="/images/logo-light.svg"
srcDark="/images/logo-dark.svg"
alt="Company logo"
width={200}
height={50}
/>Apply Cloudflare Image transformations using the transform prop for effects like blur, cropping, and format conversion.
// Grayscale effect
<Image
src="/images/photo.jpg"
alt="Grayscale photo"
width={300}
height={200}
transform={{ saturation: 0 }}
/>
// Face-aware cropping
<Image
src="/images/portrait.jpg"
alt="Portrait"
width={150}
height={150}
transform={{
fit: "cover",
gravity: "face",
}}
/>Enable adaptiveQuality to automatically adjust image quality based on the user's network conditions (using the Network Information API).
<Image
src="/images/large-photo.jpg"
alt="Adaptive quality photo"
width={1200}
height={800}
adaptiveQuality
/>| Name | Type | Default | Description |
|---|---|---|---|
src | string | Source URL of the image (used with cdn-cgi transformation) | |
srcDark | string | undefined | Alternative source for dark mode. Automatically switches based on system preference. |
alt | string | Alternative text for accessibility (required) | |
width | number | Intrinsic width of the image in pixels (required) | |
height | number | Intrinsic height of the image in pixels (required) | |
loading | LoadingStrategy | 'lazy' | Loading strategy: 'eager', 'lazy', 'lazy-near', 'lazy-visible', or 'idle' |
fetchpriority | 'high' | 'low' | 'auto' | undefined | Hint for browser fetch priority |
sizes | string | (min-width: {width}px) {width}px, 100vw | Responsive image sizes attribute |
placeholder | 'blur' | 'none' | undefined | Show a blurred low-quality placeholder while loading |
placeholderQuality | number | 30 | Quality of the placeholder image (0-100) |
placeholderBlur | number | 10 | Blur amount for the placeholder |
srcsetWidths | number[] | [320, 480, 640, 768, 1024, 1280, 1920] | Custom widths for srcset generation |
disableSrcset | boolean | false | Disable automatic srcset generation |
transform | TransformOptions | undefined | Cloudflare image transformation options |
adaptiveQuality | boolean | false | Automatically adjust quality based on network conditions |
presentation | boolean | false | If true, marks image as decorative (empty alt) |
wrapperStyles | StyleXStyles | undefined | StyleX styles for the wrapper div |
imageStyles | StyleXStyles | undefined | StyleX styles for the img element |
onLoad | () => void | undefined | Callback fired when image loads successfully |
onError | () => void | undefined | Callback fired when image fails to load |
The image module exports two main components for different use cases:
Image - For images served from the same origin using Cloudflare's cdn-cgi transformation endpoint
ForeignImage - For images hosted on Cloudflare Images (imagedelivery.net)
Use ForeignImage for images hosted on Cloudflare Images. It requires an imageId and accountHash (can be provided via context).
import {
ForeignImage,
CloudflareImagesProvider
} from "@228-co/reef/components";
// With context provider
<CloudflareImagesProvider accountHash="your-account-hash">
<ForeignImage
imageId="image-uuid-here"
alt="Cloud hosted image"
width={400}
height={300}
/>
</CloudflareImagesProvider>
// Or with direct prop
<ForeignImage
accountHash="your-account-hash"
imageId="image-uuid-here"
alt="Cloud hosted image"
width={400}
height={300}
/>ForeignImage accepts all base image props plus these additional props:
| Name | Type | Default | Description |
|---|---|---|---|
imageId | string | Cloudflare Images image ID (required) | |
accountHash | string | from CloudflareImagesContext | Cloudflare account hash. Can be provided via CloudflareImagesProvider. |
The transform prop accepts an object with Cloudflare Image transformation options:
| Name | Type | Default | Description |
|---|---|---|---|
width | number | Target width in pixels | |
height | number | Target height in pixels | |
dpr | number | Device pixel ratio multiplier | |
fit | Fit | 'scale-down' | How to fit image: 'scale-down', 'contain', 'cover', 'crop', 'pad', 'squeeze' |
quality | number | Quality | 85 | Image quality (0-100) or preset: 'high', 'medium-high', 'medium-low', 'low' |
format | Format | 'auto' | Output format: 'auto', 'avif', 'webp', 'jpeg', 'baseline-jpeg', 'json' |
gravity | Gravity | Crop position: 'auto', 'face', 'left', 'right', 'top', 'bottom', or coordinates | |
blur | number | Blur amount (1-250) | |
sharpen | number | Sharpen amount | |
brightness | number | Brightness adjustment | |
contrast | number | Contrast adjustment | |
rotate | 90 | 180 | 270 | Rotation in degrees | |
flip | 'h' | 'v' | 'hv' | Flip horizontally, vertically, or both |
Additional transform options include: zoom, trim, saturation, gamma, anim, background, metadata, segment, border, and compression.
The Image component includes built-in accessibility features:
Required alt prop ensures all images have alternative text
Use presentation prop for decorative images (sets empty alt and role="presentation")
aria-busy is set during loading for screen reader announcements
Error states display a danger icon with the original alt text
// Decorative image
<Image
src="/images/decorative-pattern.png"
alt=""
width={100}
height={100}
presentation
/>When an image fails to load, the component displays an error fallback with a danger icon. Use the onError callback to handle errors programmatically.
<Image
src="/images/might-fail.jpg"
alt="Image with error handling"
width={400}
height={300}
onError={() => {
console.error("Image failed to load");
// Track error, show notification, etc.
}}
/>