LiveVue provides several Vue composables to make interacting with LiveView from your components easier and more declarative.
useLiveVue
Returns the LiveVue instance. Can be used to access the LiveVue instance from within a LiveVue component.
function useLiveVue(): LiveHook
Usage
<script setup>
import { useLiveVue } from 'live_vue'
const live = useLiveVue()
// Push events to LiveView
live.pushEvent("increment", { amount: 1 })
</script>
Returns
The LiveView hook instance with the following properties and methods:
liveSocket
LiveSocketInstanceInterface
The Phoenix LiveSocket instance
Vue-specific context (app, props, slots)
Push an event to the LiveView serverpushEvent(event: string, payload?: object, callback?: (reply: any, ref: any) => void): number
Register a callback for events from the serverhandleEvent<T>(event: string, callback: (data: T) => void): any
Remove a previously registered event handlerremoveHandleEvent(callbackRef: any): void
Error handling
Throws an error if used outside a LiveVue component:
LiveVue not provided. Are you using this inside a LiveVue component?
useLiveEvent
Registers a callback to be called when an event is received from the server. Automatically removes the callback when the component is unmounted.
function useLiveEvent<T>(event: string, callback: (data: T) => void): void
Parameters
The event name to listen for
The callback to call when the event is received. Receives the event data as its argument.
Usage
<script setup>
import { useLiveEvent } from 'live_vue'
import { ref } from 'vue'
const notification = ref('')
useLiveEvent("notification", (data) => {
notification.value = data.message
})
</script>
<template>
<div v-if="notification" class="alert">
{{ notification }}
</div>
</template>
TypeScript support
interface NotificationPayload {
message: string
type: 'info' | 'warning' | 'error'
}
useLiveEvent<NotificationPayload>("notification", (data) => {
// data is typed as NotificationPayload
console.log(data.message, data.type)
})
useLiveNavigation
A composable for navigation using the LiveSocket instance. Works in the same way as the live_patch and live_redirect functions in LiveView.
function useLiveNavigation(): {
patch: (hrefOrQueryParams: string | Record<string, string>, opts?: { replace?: boolean }) => void
navigate: (href: string, opts?: { replace?: boolean }) => void
}
Returns
Patches the current LiveView (similar to live_patch)
hrefOrQueryParams
string | Record<string, string>
required
The URL to navigate to, or an object of query parameters to merge with the current path
If true, replaces the current history entry instead of pushing a new one
Navigates to a new location (similar to live_redirect)
If true, replaces the current history entry instead of pushing a new one
Usage
<script setup>
import { useLiveNavigation } from 'live_vue'
const { patch, navigate } = useLiveNavigation()
const goToSettings = () => {
// Update query params only
patch({ tab: 'settings', page: '1' })
}
const goToProfile = () => {
// Navigate to a different LiveView
navigate('/profile')
}
const editPost = (id) => {
// Patch with full URL
patch(`/posts/${id}/edit`)
}
</script>
<template>
<button @click="goToSettings">Settings</button>
<button @click="goToProfile">Profile</button>
<button @click="editPost(123)">Edit Post</button>
</template>
Error handling
Throws an error if LiveSocket is not initialized:
LiveSocket not initialized
useEventReply
A composable for handling LiveView events with replies. Provides a reactive way to execute events and handle their responses.
function useEventReply<T = any, P extends Record<string, any> | void = Record<string, any>>(
eventName: string,
options?: UseEventReplyOptions<T>
): UseEventReplyReturn<T, P>
Parameters
The name of the event to send to LiveView
Configuration options
Default value to initialize data with
Function to transform reply data before storing it(reply: T, currentData: T | null) => T
Returns
Reactive data returned from the event reply
Whether an event is currently executing
Execute the event with optional parameters. Returns a Promise that resolves with the server response.(params?: P) => Promise<T>
Cancel the current event execution
Usage
<script setup>
import { useEventReply } from 'live_vue'
interface User {
id: number
name: string
email: string
}
const { data, isLoading, execute } = useEventReply<User>('fetch_user')
const loadUser = async (userId: number) => {
try {
const user = await execute({ id: userId })
console.log('User loaded:', user)
} catch (error) {
console.error('Failed to load user:', error)
}
}
</script>
<template>
<button @click="loadUser(123)" :disabled="isLoading">
{{ isLoading ? 'Loading...' : 'Load User' }}
</button>
<div v-if="data">
<h3>{{ data.name }}</h3>
<p>{{ data.email }}</p>
</div>
</template>
Accumulating data
interface Message {
id: number
text: string
}
const { data: messages, execute } = useEventReply<Message[]>('load_messages', {
defaultValue: [],
updateData: (newMessages, currentMessages) => {
// Append new messages to existing ones
return currentMessages ? [...currentMessages, ...newMessages] : newMessages
}
})
const loadMore = () => {
const lastId = messages.value[messages.value.length - 1]?.id || 0
execute({ after: lastId, limit: 10 })
}
useLiveConnection
A composable for monitoring LiveView WebSocket connectivity status. Provides reactive connection state and convenience methods.
function useLiveConnection(): UseLiveConnectionReturn
Returns
Reactive connection state: "connecting" | "open" | "closing" | "closed"
Whether the socket is currently connected (computed from connectionState === "open")
Usage
<script setup>
import { useLiveConnection } from 'live_vue'
import { watch } from 'vue'
const { connectionState, isConnected } = useLiveConnection()
watch(connectionState, (state) => {
console.log('Connection state:', state)
if (state === 'closed') {
console.log('Lost connection to server')
} else if (state === 'open') {
console.log('Connected to server')
}
})
</script>
<template>
<div class="status-bar">
<span :class="{ online: isConnected, offline: !isConnected }">
{{ isConnected ? 'Online' : 'Offline' }}
</span>
<span class="text-sm">{{ connectionState }}</span>
</div>
</template>
Error handling
Throws an error if LiveSocket is not initialized:
LiveSocket not initialized
Throws an error if Socket is not available: