Skip to content

Headless Mode

useToastState() — returns raw reactive data from the queue. Use it to build a completely custom notification UI — <ToastContainer> is not needed.

ts
const { active, pending, count, has } = useToastState(context?: ToastContext)

Return value

active

ComputedRef<ToastItem[]>

Currently visible toasts (excluding hidden grouped ones).

pending

ComputedRef<ToastItem[]>

Toasts waiting for a slot.

count

ComputedRef<number>

active.value.length.

has(id)

(id: string) => boolean

Check if a toast is active.

Example — fully custom render

vue
<script setup lang="ts">
import { useToast, useToastState } from 'vue-toast-kit'

const toast = useToast()
const { active } = useToastState()
</script>

<template>
  <!-- No <ToastContainer> — render entirely from scratch -->
  <div class="my-notifications">
    <div
      v-for="t in active"
      :key="t.id"
      :class="`notification notification--${t.options.type}`"
      @mouseenter="t.pause()"
      @mouseleave="t.resume()"
    >
      <span>{{ t.message }}</span>
      <button @click="t.dismiss()">✕</button>
      <div class="progress" :style="{ width: `${t.remaining.value * 100}%` }" />
    </div>
  </div>
</template>

Each ToastItem in active is fully reactive:

id

string

Unique id.

message

string | VNode

Toast content.

options

ToastOptions (required)

Merged options.

createdAt

number

Date.now() at creation.

remaining

Ref<number>

0–1, fraction of timer remaining.

isPaused

Ref<boolean>

Timer is paused.

groupCount

Ref<number>

1 normally; >1 when grouping is active.

pause()

() => void

Pause the timer.

resume()

() => void

Resume the timer.

dismiss()

() => void

Close the toast.

update(opts)

(Partial<ToastOptions>) => void

Merge new options.