Image

Stable v1.0.2

An image component with lazy loading, a loading/error fallback state, and a built-in lightbox for zooming in, the stuff you would normally bolt on yourself.

Interactive Playground

Experiment with memory-safe Blob parsing, interactive lightboxes, and failure states.

Image Source (Blob / String)
Layout & Shape
Rounded (Default)
Cover
Features
Content & Accessibility
Loading & Network
None (Default)
Auto
Group / Avatar Mode
Scenic mountain view
Live Source Code
<Image
  :src="'https://picsum.photos/id/1018/1000/600'"
  alt="Scenic mountain view"
  fallback="https://picsum.photos/id/1015/400/400"
  previewable
  :width="250"
  :height="250"
/>

Implementation Examples

Image
Did you check the new image component?
Yes! The text scaling and layouts are flawless now.
Seen by everyone
Image
Image
Image
Image
+1

1. Group Arrays (Messenger "Seen By")

By simply passing an array of URLs to the src prop, the component natively handles overlapping margins, z-indexing, and generates a perfectly-scaled +N badge automatically based on the provided width.

<div class="flex items-center gap-1.5 justify-end mt-0.5">
  <Icon icon="lucide:check-circle-2" class="w-3.5 h-3.5 text-muted" />
  <span class="text-[10px] text-muted font-medium mr-1">Seen by everyone</span>

  <Image
    :src="messengerAvatars"
    shape="circle"
    :width="22"
    :max="4"
    borderColor="border-[#F0F5FF]"
  />
</div>
#error Slot
Image
#preview-actions Slot
Image

2. Overriding Slots

You can completely replace the failure UI using the #error slot. Using the #preview-actions slot, you can inject custom buttons directly into the lightbox toolbar.

<Image src="bad-url.jpg" :width="160" :height="160" shape="rounded">
  <template #error>
    <div class="flex flex-col items-center justify-center bg-danger/10 text-danger w-full h-full border border-danger/20 rounded-3xl">
      <Icon icon="lucide:alert-triangle" class="w-8 h-8 mb-2 opacity-80" />
      <span class="text-xs font-bold px-2">Load Failed</span>
    </div>
  </template>
</Image>

<Image src="https://picsum.photos/id/44/800/800" :width="160" :height="160" shape="rounded" previewable>
  <template #preview-actions>
    <button class="flex cursor-pointer items-center gap-1.5 p-2 px-3 text-primary hover:bg-primary/10 rounded-full font-bold">
      <Icon icon="lucide:download" class="w-4 h-4" />
      <span class="text-xs hidden sm:inline">Save</span>
    </button>
    <div class="w-px h-5 bg-(--border-main) mx-1"></div>
  </template>
</Image>
Image
Image
Image
Image
Image
Image
Image
Image

3. Responsive Galleries & Grids

By passing width="100%", the images seamlessly adapt to parent layout constraints (like CSS Grid or Flexbox), while retaining consistent height and cropping rules.

<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3 w-full">
  <Image
    v-for="n in 8"
    :key="n"
    :src="`https://picsum.photos/id/${n + 50}/600/400`"
    width="100%"
    :height="120"
    shape="rounded"
    previewable
    class="shadow-sm border border-main/20 hover:shadow-md transition-shadow"
  />
</div>
Image

4. High-Resolution Lazy Loading

Notice the beautiful shimmer effect before the 4K image finishes downloading. Because of loading="lazy", images further down the page hold this state until the user scrolls them into view.

<div class="w-full max-w-3xl h-64 sm:h-96 rounded-md overflow-hidden shadow-lg border border-main/20">
  <Image
    :src="`https://picsum.photos/id/10/4000/3000`"
    shape="rounded"
    width="100%"
    height="100%"
    lazy
    previewable
  />
</div>

API Reference

Props

Name
Type
Default
Description
src
string | Array | Blob | File
undefined
The image source. If an array is passed, automatically switches to Avatar Group mode.
alt
string
"Image"
Accessibility text for the image.
fallback
string
undefined
A fallback image URL to load if the primary src fails.
previewable
boolean
false
Enables the interactive fullscreen lightbox (supports zooming, panning, and keyboard shortcuts).
lazy
boolean
true
Applies native `loading="lazy"` and `decoding="async"` for optimal network performance.
fetchpriority
"high" | "low" | "auto"
"auto"
Hints the browser on resource loading priority.
crossorigin
string
undefined
Configures CORS requests for the element.
srcset
string
undefined
Native `srcset` for responsive images -- a comma-separated list of image URLs paired with a width or pixel-density descriptor, letting the browser pick the best-fit resolution.
fit
string
"cover"
Maps to CSS object-fit. Options: cover, contain, fill, scale-down, none.
shape
"rounded" | "circle" | "square"
"rounded"
Controls border radius. Use "circle" for Avatars.
width
number | string
undefined
Explicit width (e.g., pass `:width="200"` for pixels, or `width="100%"`).
height
number | string
undefined
Explicit height. (Note: internally forced to equal width if shape="circle" to prevent ovals).
max
number
4
[GROUP MODE]: Maximum number of images to display before generating the +N badge.
stacked
boolean
true
[GROUP MODE]: Applies negative margins to overlap the images in an array.
borderColor
string
"border-surface"
[GROUP MODE]: Tailwind class for the image border color to create the overlapping cutout effect.
skeletonClass
string
undefined
Custom CSS classes to inject into the loading skeleton wrapper.

Slots

Slot Name
Description
loading
Custom content to display while the image is downloading. Replaces the default shimmer skeleton.
error
Custom content to display if the image fails to load. Replaces the default broken image icon and fallback behavior.
preview-actions
Inject custom buttons (e.g., Download, Share) into the Lightbox toolbar. Renders alongside default controls.