Image
A size-aware <img> that routes Oztix-CDN assets through the resize/transcode proxy.
Pass a width. The component requests a right-sized WebP plus a srcSet, cutting download bytes and decoded memory. Non-Oztix URLs and calls without a width render a plain <img>, so external thumbnails still work.
Every image sits on a bg-subtle tint as a placeholder. It drops once the image loads, so it never lingers behind a transparent image. Override it with another semantic background utility like bg-sunken.
Import
import { Image } from '@oztix/roadie-components'
Examples
Default
The simplest correct usage: a src, an alt, and a width. The component serves a right-sized WebP with a 1x/2x srcSet. Add height to reserve space. (Omit width and it falls back to a plain <img> of the original file.)
Resizing Oztix assets
Pass width (the 1x render size in CSS pixels). The component rewrites src to ?width=&format=webp and builds a srcSet. One prop decides whether small screens get small files: sizes.
Fixed-size images render at the same size everywhere. Think logos, avatars, fixed thumbnails. Just pass width. You get a 1x/2x srcSet and sizes='${width}px'. Retina screens get the crisp 2x. Nobody downloads more.
<Image src={url} alt='Show artwork' width={360} />// srcSet = 360w, 720w sizes = 360px
Fluid images fill their container and change size across breakpoints. Think full-width heroes or cards in a grid. Add sizes to describe how wide the image renders. Roadie then builds a small-to-2x ladder for you. This is the lever that loads a small file on a phone and a large one on a desktop. No manual widths needed.
The example below is fluid. Resize the window with the network panel open: the browser fetches a smaller file as the column narrows.
Match sizes to the layout. Use '100vw' for full-bleed. Use '(min-width: 768px) 33vw, 100vw' for a 3-up grid. Pass widths only to override the generated ladder.
Add height to crop to a fixed box. It is sent to the proxy and scaled per srcSet entry to keep the ratio.
<Image src={url} alt='Show artwork' width={360} height={240} />// src = …?width=360&height=240&format=webp
Trimming transparent space
Logos often ship with transparent padding. Set autotrim to crop it server-side so the artwork fills the box. Pair it with a proportional width (no height) to keep the trimmed ratio.
<Image src={logoUrl} alt='Event logo' width={300} autotrim />// …?width=300&format=webp&autotrim=1
Quality and advanced commands
quality (1–100) trades fidelity for bytes. For anything else the proxy supports, like resize mode, anchor, or background colour, use the params escape hatch. Entries merge verbatim into the query.
Supported params keys (ImageSharp.Web): rmode, ranchor, rxy, rsampler, compand, orient, bgcolor, autoorient, pngcolortype.
Reserving layout
Reserve space to avoid layout shift in one of two ways:
width+heightsets thewidth/heightattributes and anaspect-ratiostyle. It also sendsheightto the proxy, cropping to that box.width+ anaspect-*utility reserves the box without a fixed height. The resize stays proportional (no crop). The aspect class lands on the layout box, so pair it withw-full.
The source is a 2752×1536 6.1 MB PNG. Resized to WebP it ships ~280 KB. In short: aspect-* or height reserves space; height also crops.
Hero imagery
A full-bleed hero is a fluid image that's also the LCP element. Set sizes='100vw' so Roadie builds the ladder, then add priority for eager loading and fetchpriority="high". Reach for widths only to hand-tune the ladder.
Art direction (different crops per breakpoint)
widths and sizes do resolution switching: the same image at different sizes. Art direction is different. It serves a different URL or crop per breakpoint, like a tall portrait on mobile and a wide banner on desktop. Pass sources for that. The component renders a <picture> with one <source> per entry and keeps src as the fallback <img>. Each source inherits format, quality, autotrim, params, and width unless it overrides them.
<picture> only swaps the file. The layout box is still CSS. So change the shape per breakpoint with a responsive aspect-* utility, and don't set a top-level height (it would pin one aspect ratio across every breakpoint). Resize the window to see it switch.
Phones (under 640px) load a real 600×800 portrait crop in a 3:4 box. Wider screens get the proportional image in a 16:9 box. Pass a different src per source to serve entirely separate images.
Blur-up placeholder
Set placeholder='blur' to show a tiny preview that fades into the full image on load. Use it as the default treatment for content imagery. The preview comes from the Oztix proxy automatically. Pass width and height so layout is reserved while it loads.
For non-Oztix images, or to override the auto preview, pass blurDataURL. It takes a data URI or any small image URL.
Deferred loading in carousels
Embla mounts every slide in the DOM, so native loading='lazy' over-fetches off-screen slides. Set defer to hold the src until the tile nears the viewport (via IntersectionObserver). Layout is still reserved from width and height.
Helpers
Building a custom composition? Think LQIP banners, CSS background-image, or a server-rendered <img srcset>. The pure URL helpers ship from @oztix/roadie-core/image without the React component.
Pair the srcSet with a sizes attribute on your <img> so the browser actually picks the small file on small screens.
Hero image with blur (Vue)
Vue consumers don't get the React component, but the helpers give the same result. Derive a tiny LQIP and a responsive srcSet from the source. Then fade the full image in over the blurred preview. Style with Roadie/Tailwind utilities. Only the dynamic LQIP URL needs an inline :style.
A hero is above the fold, so it loads eagerly with fetchpriority='high'. A cached image may fire @load before hydration. Guard it on mount with if ((e.target as HTMLImageElement).complete) loaded = true if that matters for your app.
Guidelines
Pass width to optimise Oztix images
<Image src={oztixUrl} alt='…' width={600} />
Do
width turns on resizing. The CDN returns a right-sized WebP plus a srcSet.
<Image src={oztixUrl} alt='…' />
Don’t
Without width the original file is served (here a 6.1 MB PNG). Non-Oztix URLs always pass through, so size those at the source.
Add sizes for fluid images so phones get small files
<Image src={url} alt='…' width={1600} sizes='100vw' />
Do
For an image that fills its container, set sizes to how wide it renders. Roadie builds a small→large ladder, so a phone downloads a small file and a desktop a large one.
<Image src={url} alt='…' width={1600} className='w-full' />
Don’t
A full-width image with no sizes is treated as fixed at its width, so small screens still download the large file.
Reserve space to avoid layout shift
<Image src={url} alt='…' width={800} height={450} />// or, no crop:<Image src={url} alt='…' width={800} className='aspect-video w-full' />
Do
Give the box a ratio with height (also crops to it) or an aspect-* utility plus w-full (proportional).
<Image src={url} alt='…' width={800} className='w-full' />
Don’t
width alone reserves no height, so the page reflows when the image loads.
Prioritise only the LCP image
<Image src={heroUrl} alt='…' width={1600} sizes='100vw' priority />
Do
Mark the single largest above-the-fold image priority; everything else stays lazy by default.
// priority on every card in a grid
Don’t
Prioritising everything floods the network on first paint and hurts LCP.
Defer images inside carousels
<Card.Image src={url} alt='…' width={360} defer />
Do
Use defer in horizontally-scrolled surfaces. Slides load only as they near the viewport.
<Card.Image src={url} alt='…' width={360} />
Don’t
Native loading='lazy' still fetches off-screen slides, because Embla mounts them all in the DOM.
Accessibility
altis required. Write a concise description of what the image shows.width/heightreserve layout, reducing cumulative layout shift for assistive-tech and keyboard users alike.
API reference
Image
Image URL. Oztix-CDN hosts get the resize/transcode rewrite; everything else passes through.
Alt text describing the image. Required.
1x render width in CSS pixels. Drives the default `srcSet`/`sizes` and reserves layout. Omit to render a plain pass-through `<img>`.
Target/intrinsic height. Reserves layout (via `aspect-ratio`) and, when set alongside `width`, is sent to the proxy so it crops to both dimensions.
Explicit srcSet ladder. Defaults to `[width, width * 2]`.
`<img sizes>` describing how wide the image renders (e.g. `'100vw'`). Set it for fluid images so Roadie builds a responsive ladder and small screens load small files. Defaults to `${width}px` (fixed size).
Marks the image as LCP-critical: eager loading + `fetchpriority="high"`.
Defaults to false.
Output format. Defaults to `webp`.
Encoder quality, 1–100. Lower trades fidelity for bytes.
Crop surrounding transparent space server-side (ImageSharp `autotrim=1`). Useful for logos padded with transparency. Takes effect with `width`.
Escape hatch for any other ImageSharp.Web command (`rmode`, `ranchor`, `bgcolor`, etc.), merged verbatim. Takes effect with `width`.
Blur-up placeholder: show a tiny low-quality preview, then fade the full image in on load. `'blur'` wraps the image in a positioned element. The preview is derived from the Oztix proxy by default; pass `blurDataURL` for non-Oztix images or to override.
Defaults to empty.
Explicit preview source for `placeholder='blur'`. Required for non-Oztix images.
Art direction: render a `<picture>` with a `<source>` per breakpoint, each able to use a different URL/crop. The component `src` stays the fallback `<img>`. Each entry inherits `format`/`quality`/`autotrim`/`params`/`width` unless it overrides them.
Defer loading until the image nears the viewport via IntersectionObserver. Use inside horizontally-scrolled surfaces (e.g. Carousel) where native `loading='lazy'` over-fetches. Ignored when `priority` is set.
Defaults to false.