Image
Render a base64 Experimental_GeneratedImage from the Vercel AI SDK as an inline data-URI img with sensible chrome defaults.
Overview
Image is the surface for model-generated images. It accepts an Experimental_GeneratedImage from the Vercel ai package (base64 string + media type) and renders it as a single <img> with a data URI src, a default rounded-md border and max-w-full to keep layouts safe.
There is no fetch, no signed URL flow and no client-side decoding logic - by the time the AI SDK hands you the part, the base64 is ready. This primitive's only job is to render it consistently across artifacts, chat messages and dashboards.
Use it inside Artifact for image-only artifacts, inside MessageContent for inline replies, or standalone wherever a generated image appears in your UI.
Preview
'use client';import { Image } from '@gremorie/rx-ai';// A small solid PNG (indigo), base64-encoded — stands in for an AI-generated// image returned by the SDK as an Experimental_GeneratedImage.const SAMPLE_IMAGE_BASE64 = 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKklEQVR4nGNITvtIU8QwasGoBaMWjFowasGoBaMWjFowasGoBaMWjFowasGoBaMWDBULAMgi6FsP9QbPAAAAAElFTkSuQmCC';export function ImagePreview() { return ( <div className="flex justify-center"> <Image alt="AI-generated swatch" base64={SAMPLE_IMAGE_BASE64} className="w-48" mediaType="image/png" uint8Array={new Uint8Array()} /> </div> );}Installation
bash npx gremorie@latest add rx-image bash pnpm dlx gremorie@latest add rx-image bash yarn dlx gremorie@latest add rx-image bash bunx --bun gremorie@latest add rx-image Brings in the ai package types as a peer dependency.
Usage
import { Image } from "@gremorie/rx-ai";
export function Example({ image }) {
return (
<Image
base64={image.base64}
mediaType={image.mediaType}
alt="Bar chart of weekly conversions"
/>
);
}Angular edition planned for Phase 5h. Use the React edition for now, or open an issue to prioritize this primitive.
API
<Image>
Extends Experimental_GeneratedImage from the ai package.
| Prop | Type | Default | Description |
|---|---|---|---|
base64 | string | - | Required. The base64-encoded image data. Used to build the data: URI. |
mediaType | string | - | Required. Mime type ("image/png", "image/jpeg", "image/webp", ...). Used in the data: URI prefix. |
uint8Array | Uint8Array | - | Forwarded from Experimental_GeneratedImage but ignored by the renderer. The data URI is built from base64. |
alt | string | - | Required for a11y. Description of the image content. Pass a short factual description, not "AI generated image". |
className | string | - | Extra classes on the <img>. Merged with the default h-auto max-w-full overflow-hidden rounded-md. |
All other <img> attributes flow through (e.g. width, height, loading, decoding, style).
Composition
- Render with the part from the AI SDK. The
Experimental_GeneratedImageshape is what the SDK hands you inimage-partmessages. - Inside
Artifactwhen the image is the artifact itself. - Inside
MessageContentwhen the image is inline content in a chat reply. - With sizing via
className(size-32,max-w-md) or explicitwidth/heightprops for layout stability.
Variations
Inline generated chart inside a message
Drop the image inside MessageContent alongside text and citations.
<Message from="assistant">
<MessageContent>
<MessageResponse>Here is the weekly conversion trend:</MessageResponse>
<Image
base64={chart.base64}
mediaType={chart.mediaType}
alt="Weekly conversion bar chart, 23% up vs. previous week"
/>
</MessageContent>
</Message>Image-only artifact with download action
<Artifact>
<ArtifactHeader>
<ArtifactTitle>logo.png</ArtifactTitle>
<ArtifactActions>
<ArtifactAction
tooltip="Download"
icon={DownloadIcon}
onClick={download}
/>
<ArtifactClose />
</ArtifactActions>
</ArtifactHeader>
<ArtifactContent>
<Image
base64={logo.base64}
mediaType={logo.mediaType}
alt="Generated logo"
/>
</ArtifactContent>
</Artifact>Constrained dimensions
When the layout needs a fixed image size, pass explicit dimensions.
<Image
base64={image.base64}
mediaType={image.mediaType}
alt="Thumbnail preview"
width={120}
height={120}
className="size-30 object-cover"
/>Lazy load below the fold
<Image
base64={image.base64}
mediaType={image.mediaType}
alt="..."
loading="lazy"
decoding="async"
/>Accessibility
- Always supply
alt: There is no built-in fallback. Pass a factual description of what the image contains - for a chart, summarize the trend in words; for a logo, name the brand. - Decorative images: If the image is purely decorative, pass
alt=""(not omit) so screen readers skip it cleanly. - No loading state by default: Base64 images render synchronously, so the typical "loading shimmer" pattern does not apply. If you stream the image (rare for AI SDK output), render a
Skeletonnext to a deferredImage. - Reduced motion: There is no animation. Honor user prefs only if you wrap the image in your own transition.
- Color contrast: When the image carries text (e.g. a generated chart), independently verify that the rendered text passes contrast for embedded content - the primitive cannot inspect the bytes.
Related
- Artifact - the card chrome around image artifacts
- Message - the chat turn that may inline an image
- Open in Chat - send a generated image back into the conversation