Renders a raster image (JPG/PNG/WebP/AVIF, …) through the @uxf/resizer service, with automatic responsive <source> generation and a graceful empty-state fallback. SVG sources are detected and rendered as-is (no resizer).
Reach for RasterImage for any content image that should be served from the UXF resizer: it produces a <picture> with avif/webp/original <source> sets and a fallback <img>, and renders a consistent placeholder when the source is missing. For a user's circular profile picture use Avatar instead.
There is no @uxf/form twin — RasterImage is a display primitive, not a form field.
import { RasterImage } from "@uxf/ui/raster-image";
<RasterImage alt="A beautiful landscape" height={300} loading="lazy" src="images/landscape.jpg" width={400} />
src accepts an ImageSource from @uxf/core/utils/resizer — a plain URL string, an ImageResponse ({ uuid, extension, width?, height?, … }), or Next.js StaticImageData. Provide at least one of width / height; supplying both requests exact dimensions from the resizer. Omitting both is a TypeScript error by design.
Pass widths (and optionally heights) to emit multiple candidate sources, and breakpoints (named breakpoint → CSS min-width value) to attach media queries. When breakpoints is omitted, the breakpoints configured on UiContextProvider (rasterImage.breakpoints) are used.
<RasterImage
alt="Hero"
breakpoints={{ sm: "36em", md: "48em", lg: "64em" }}
height={540}
src="images/hero.jpg"
widths={[360, 640, 960, 1280]}
width={960}
/>
When src is null/undefined, or no resizer URL can be built, the component renders a 1×1 transparent EmptyImage placeholder. Supply noImageContent to overlay custom content:
<RasterImage alt="Missing" height={150} noImageContent={<span>No image</span>} src={null} width={200} />
type RasterImageProps = {
// ...RasterImageDimensions (see below)
} & {
alt: string;
// ...
};
| Prop | Type | Default | Description |
|---|---|---|---|
alt |
string |
— | Required. Alt text; use "" for purely decorative images. |
src |
ImageSource | null | undefined |
— | Required. Resizer source (URL string, ImageResponse, or StaticImageData). null/undefined renders the empty placeholder. |
width |
number |
— | Requested width. See dimensions rule below. |
height |
number |
— | Requested height. See dimensions rule below. |
mode |
"contain" | "cover" | "responsive" |
— | Object-fit helper. contain/cover add positioning CSS classes; responsive adds no class. |
widths |
number[] |
— | Candidate widths for responsive <source> sets. |
heights |
number[] |
— | Candidate heights for responsive <source> sets. |
breakpoints |
Partial<Record<string, string>> |
UiContext value |
Named breakpoint → CSS min-width (e.g. { sm: "36em" }) attached as <source media>. |
quality |
Quality |
"original" |
Requested resizer quality (getImgQuality(quality, "original")). |
options |
ImageSourcesOptions |
— | Passed to the resizer/source helpers. Adds isAvifDisabled / isWebPDisabled to skip those formats. |
loading |
"eager" | "lazy" |
— | Native <img loading>. |
noImageContent |
ReactNode |
— | Content overlaid on the empty-state placeholder. |
className |
string |
— | Class on the wrapper <picture>. |
imgClassName |
string |
— | Class on the <img>. |
role |
AriaRole |
— | Accepted by the type but currently not forwarded to the rendered element. |
Dimensions rule: the type requires at least one of width / height — either both, width only, or height only.
<picture> with avif + webp + original <source> sets plus a fallback <img>. The fallback <img> width/height are derived via getImgElementWidth/getImgElementHeight.getSvgImgUrl(src) matches): renders a plain <img> inside <picture>, bypassing the resizer.src falsy or no resizer URL → transparent EmptyImage placeholder with optional noImageContent.Wrapper/image CSS hooks: .uxf-raster-image (+ --contain / --cover) and .uxf-raster-image__img (+ --contain / --cover).
Import the component stylesheet once in your global CSS:
@import url("@uxf/ui/css/raster-image.css");
Also requires the global @uxf/ui token layer, set up once per app — see @uxf/ui setup.