AbsoluteJS

Vue Components

AbsoluteJS provides an Image component plus StreamSlot and SuspenseSlot for Vue. Import them from @absolutejs/absolute/vue or @absolutejs/absolute/vue/components.

#Image Component

The Vue Image component is a local component that uses the shared imageUtils module under the hood. It provides responsive srcset generation, WebP/AVIF format negotiation, and on-demand optimization through the /_absolute/image endpoint.

HTML
<template>
  <Image
    src="/images/hero.jpg"
    alt="Hero banner"
    :width="1200"
    :height="600"
    priority
  />

  <!-- Fill mode -->
  <div style="position: relative; width: 100%; height: 400px;">
    <Image
      src="/images/bg.jpg"
      alt="Background"
      fill
      style="object-fit: cover;"
    />
  </div>
</template>

<script setup>
import { Image } from '@absolutejs/absolute/vue';
</script>

#Image Props

The Vue Image component accepts the same props as the React Image component:

srcpath to the source image (required)
altalternative text for accessibility (required)
widthintrinsic width in pixels. Required unless fill is set.
heightintrinsic height in pixels. Required unless fill is set.
fillwhen true, the image fills its parent container
qualityoutput quality from 1 to 100
sizesresponsive sizes attribute
prioritypreload the image and disable lazy loading
placeholderplaceholder strategy while loading
blurDataURLbase64 data URL for blur placeholder
loading"lazy" or "eager"
unoptimizedskip optimization and serve the original
styleinline styles
classNameCSS class name
onLoadcallback when the image finishes loading
onErrorcallback when the image fails to load

#Fill Mode

When fill is set, the image uses absolute positioning to fill its parent container. You do not need to provide width or height. The parent must have position: relative.

Note that Vue's Teleport component has limitations with SSR: it cannot teleport to elements that don't exist in the server-rendered HTML. The Image component handles preload link injection without Teleport, so priority images work correctly during SSR.

#Streaming Components

Vue supports both layers of AbsoluteJS streaming. Use StreamSlot when you want the raw transport and will provide fallback and resolved HTML yourself. Use SuspenseSlot when you want to author fallback and resolved UI as normal Vue markup.

These primitives are only enabled when the route uses handleVuePageRequest with { collectStreamingSlots: true } in the options argument.

SuspenseSlot uses Vue-authored fallback and default slots on top of the shared out-of-order transport, so slot resolution order can differ from declaration order without forcing you back into string HTML.

Raw transport with StreamSlot:

HTML
<script setup lang="ts">
import { StreamSlot } from '@absolutejs/absolute/vue/components';
</script>

<template>
  <main>
    <h1>Dashboard</h1>

    <StreamSlot
      id="vue-activity"
      fallback-html="<div class=&quot;card-skeleton&quot;>Loading activity...</div>"
      :resolve="async () => renderActivityHtml(await getActivity())"
    />
  </main>
</template>

Framework-native transport with SuspenseSlot:

HTML
<script setup lang="ts">
import { SuspenseSlot } from '@absolutejs/absolute/vue/components';
</script>

<template>
  <main>
    <h1>Dashboard</h1>

    <SuspenseSlot id="vue-activity" :promise="getActivity()" :timeout-ms="5000">
      <template #fallback>
        <ActivitySkeleton />
      </template>
      <template #default="{ value }">
        <ActivityPanel :activity="value" />
      </template>
    </SuspenseSlot>
  </main>
</template>