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.
<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:
fill is set.fill is set."lazy" or "eager"#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:
<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="card-skeleton">Loading activity...</div>"
:resolve="async () => renderActivityHtml(await getActivity())"
/>
</main>
</template>Framework-native transport with SuspenseSlot:
<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>