Prepared Docs

Prepared Docs

⌘K

    Loading navigation…

User

  1. Components
  2. Image
  3. Usage

Image

Usage

Overview

Image renders responsive raster and URL-based images as a native <img>, and trusted local SVGs as an inline <svg>. It is modeled on the Next.js Image layout and performance subset: intrinsic width/height, fill, objectFit, objectPosition, lazy loading, priority preloading, and blur placeholders. Use inline SVG mode when size and class changes must apply to the actual <svg> node (for example application logos).

Design-system Image (@prepared911/ui/image)

The design-system Image keeps the URL path (src, optional srcDark) and adds an inline SVG path:

  • Pass svg={Wordmark} where Wordmark is ComponentType<SVGProps<SVGSVGElement>> (an SVGR ?react import). Do not also pass src.
  • Size the mark with size={{ inline, block }}. Each axis is a space-scale step (--space-*), for example 32 or 80. There is no style, className, or numeric width / height.
  • Paint stays currentColor, so the mark follows surrounding text color.
  • A meaningful alt (LocalizedMessage) becomes role="img" and aria-label. decorative, or alt="", sets aria-hidden="true" and focusable="false".
  • Do not put title or desc in the SVG. They would duplicate the accessible name.
  • Icon and BrandMark remain the glyph set and the Axon product mark. Image is the wordmark or other trusted SVG component.

A ui-core call <Image svg={Mark} width={153} height={80} /> becomes <Image svg={Mark} size={{ inline: 128, block: 80 }} />. 153 is not a space step; 128 is the nearest step at or below it.

When to use

  • Logos, illustrations, and photos where intrinsic dimensions or responsive sizes help avoid layout shift.
  • Hero or card imagery that benefits from lazy loading, priority preloading, or a blur placeholder.
  • fill layouts inside a positioned container (covers, thumbnails).
  • Trusted local SVG logos via svg={ImportedSvg} when size and class changes must affect the actual <svg> node.

When not to use

  • Icons and glyphs — use Icon with SVGAsset.
  • User avatars — use Avatar.
  • Decorative imagery with no semantic meaning — prefer Icon or hide from assistive tech with an empty alt only when appropriate.

Variants

ModePropRendersWhen to choose
URL / rastersrcNative <img>Photos, remote assets, URL SVGs (rendered safely as <img>)
Inline SVGsvgInline <svg> via SVGR (?react import)Trusted local logos and illustrations that must resize with CSS
Themed URLlightSrc / darkSrcTwo native <img> elementsLogos or marks that differ by light/dark theme
Themed inline SVGlightSvg / darkSvgTwo inline <svg> elementsTrusted local logos that differ by light/dark theme

For URL SVGs, pass src and the component renders a native <img>. For trusted local SVGs imported via SVGR (?react), pass svg to render the actual <svg> element.

Theming

Pass lightSrc/darkSrc or lightSvg/darkSvg when a logo or mark needs a different asset in light and dark mode. Visibility follows the same theme class selectors as other ui-core styles:

  • Light: ancestor .light, .light-theme, or .radix-themes.light
  • Dark: ancestor .dark, .dark-theme, or .radix-themes.dark

Image renders both variants and uses CSS (display) to reveal the one that matches the active theme. This follows the Next.js theme-aware image pattern (render both, toggle with CSS) adapted to this repo's class-based theming. Benefits:

  • SSR-safe — no JavaScript theme branch at render time; the correct variant appears as soon as the theme class is on <html>.
  • No flash — the off-theme variant is hidden before paint when the theme class is set server-side.
  • Accessible — the hidden variant uses display: none, so it is removed from the accessibility tree (no duplicate alt announcement).

In themed modes, id is applied to a display: contents themed root (not to either variant) so SSR and hydration stay aligned without useTheme() branching. onLoad and onError are forwarded to both variants so a background-loaded image still notifies consumers after a theme switch.

Name assets by contrast (for example logo-dark-new.svg is the dark mark used on light backgrounds), not by the active theme. Next.js apps that rely heavily on next/image optimization may still use a local wrapper (for example docs ThemedImage) for raster-heavy imagery.

Anatomy

  • URL mode: A single <img> with BEM classes for fill, object-fit, object-position, and optional blur placeholder. When sources is set, that <img> sits inside a layout-transparent <picture> so fill / object-fit still resolve on the image itself.
  • Inline SVG mode: The imported SVG component with the same layout BEM classes applied directly to the <svg> node. Numeric width/height are forwarded as SVG attributes (matching URL mode); omit them to use intrinsic/viewBox sizing.
  • Themed modes: Both light and dark sources mount; CSS reveals the active variant.

Responsive and format negotiation

URL mode accepts:

PropRole
srcSetNative srcset candidate set; pair with sizes so the browser can pick a width
sizesNative sizes hint — only meaningful alongside srcSet or a sources entry
sourcesArray of { srcSet, type?, media?, sizes? } rendered as <source> elements ahead of src

ImageMediaType covers the common MIME gates (Avif, Webp, Png, Jpeg, Gif, Svg). Order sources newest-first; keep src as a universally supported fallback.

Content guidelines

  • Alt text: Every meaningful image needs a concise alt that describes purpose, not decoration. Pass decorative instead only when the image is purely decorative and surrounding context carries the meaning.
  • Dimensions: Provide width and height (or fill inside a sized container) to reserve layout space and reduce cumulative layout shift.
  • Logos: Prefer inline SVG mode for brand marks that must scale crisply at multiple sizes.

Behavior and states

  • Loading: Defaults to lazy loading (ImageLoading.Lazy). Set priority for above-the-fold imagery (eager load, high fetch priority).
  • Placeholder: ImagePlaceholder.Blur with blurDataURL shows a low-resolution preview until the main image loads (URL mode only). Changing src resets the blur state so the placeholder can reappear.
  • Object fit / position: ImageObjectFit and ImageObjectPosition map to CSS via BEM modifiers.
  • Fill: When fill is true, omit width/height and place Image inside a positioned ancestor.

Server-only Next.js Image props (loader, quality, unoptimized) are not supported in ui-core.

Best practices

Do

  • Reserve space with intrinsic dimensions or a sized fill container.
  • Use priority sparingly for hero or LCP imagery.
  • Import trusted SVGs with ?react and pass them via svg when CSS must target the SVG node.
  • Use lightSvg/darkSvg or lightSrc/darkSrc for theme-aware logos instead of hand-rolling useTheme() branches.

Don't

  • Inline remote or untrusted SVG markup — use src (native <img>) instead.
  • Branch on useTheme() in render to swap logo src/svg — use themed props so CSS handles the toggle.
  • Use Image for icon-sized glyphs — use Icon.
  • Rely on images alone to convey critical information — pair with visible text.

Accessibility

  • Required alt for non-decorative images; empty alt for decorative images only.
  • Inline SVG mode sets role="img" and aria-label when alt is non-empty; decorative images get aria-hidden and focusable={false}.
  • See Accessibility for full guidance.

Related Components

  • Icon for glyphs and UI icons.
  • Avatar for user profile images.
  • Box for positioned fill containers.

Previous

Icon Toggle / Accessibility

Next

Image / API and Development

On this page

Overview
Design-system Image (@prepared911/ui/image)
When to use
When not to use
Variants
Theming
Anatomy
Responsive and format negotiation
Content guidelines
Behavior and states
Best practices
Accessibility
Related Components