Skip to content

useRealtimeNotifications ​

An optional live feed. Point VITE_REALTIME_URL at a WebSocket or an event stream and notifications arrive on their own.

Import ​

ts
import { useRealtimeNotifications } from '@shared/composables/useRealtimeNotifications'

Signature ​

ts
function useRealtimeNotifications(): {
  connected: Ref<boolean>
  close: () => void
}

Returns ​

MemberTypeDescription
connectedRef<boolean>Whether the connection is open right now.
close() => voidCloses it and stops reconnecting. Runs automatically on scope dispose.

Configuration ​

One environment variable:

bash
VITE_REALTIME_URL=wss://api.example.com/notifications

A ws:// or wss:// URL opens a WebSocket. Anything else opens an EventSource, so an https:// endpoint gives you server-sent events with no code change.

Unset, the composable does nothing and returns a connected that stays false. It is safe to call unconditionally.

The message shape ​

Each message is JSON:

json
{
  "type": "success",
  "title": "Payment received",
  "description": "Invoice INV-2043 has been paid in full.",
  "link": "/finance/invoices"
}
KeyFalls back to
type'info'
title'Notification'
descriptionnothing
linknothing

A malformed payload is ignored rather than throwing, so one bad message cannot take the feed down.

Example ​

vue
<script setup lang="ts">
import { useRealtimeNotifications } from '@shared/composables/useRealtimeNotifications'

const { connected } = useRealtimeNotifications()
</script>

<template>
  <span :aria-live="'polite'">
    {{ connected ? 'Live' : 'Offline' }}
  </span>
</template>

Notes ​

  • Reconnection backs off exponentially, starting at one second and doubling to a ceiling of thirty. A successful open resets it, so a brief drop reconnects quickly and a dead endpoint is not hammered.
  • close() sets a flag that stops any pending reconnect, so closing deliberately does not immediately reopen.
  • It connects as soon as it is called and closes on onScopeDispose, so calling it from a component's setup is all the lifecycle management needed.
  • Messages are pushed straight into useNotifications, which is persisted — so a message that arrives is still there after a reload.
  • A WebSocket error closes the socket, which triggers the reconnect path. There is one route back, not two.