LiveVue 1.1
Examples Shared Props

Headless Shared Props

v1.1

Use a headless LiveVue component (no v-component) as a global state provider. Other components read shared props via useLiveVue(id).

What this example shows

1
Headless Component
.vue with id but no v-component
2
useLiveVue(id)
Read shared props by id
3
Reactive Updates
Server changes propagate to consumers
SharedProps.vue
<script setup lang="ts">
import { computed } from 'vue'
import { useLiveVue } from 'live_vue'

defineProps<{
  pageTitle: string
}>()

const shared = useLiveVue("shared-state")

const user = computed(() => shared?.vue.props.user)
const theme = computed(() => shared?.vue.props.theme)
</script>

<template>
  <div
    class="rounded-xl border overflow-hidden transition-colors duration-300"
    :class="theme === 'dark'
      ? 'bg-base-300 border-base-content/20'
      : 'bg-base-100 border-base-300'"
  >
    <div
      class="px-4 py-3 border-b flex items-center justify-between transition-colors duration-300"
      :class="theme === 'dark'
        ? 'border-base-content/20 bg-base-content/5'
        : 'border-base-300 bg-base-200'"
    >
      <span class="text-sm font-medium">{{ pageTitle }}</span>
      <span class="text-xs px-2 py-0.5 rounded-full bg-secondary/20 text-secondary">
        {{ theme }}
      </span>
    </div>

    <div class="p-6 space-y-4">
      <div v-if="user" class="flex items-center gap-3">
        <div class="w-8 h-8 rounded-full bg-primary/20 flex items-center justify-center text-primary text-sm font-bold">
          {{ user.name.charAt(0) }}
        </div>
        <div>
          <p class="text-sm font-medium">{{ user.name }}</p>
          <p class="text-xs text-neutral">{{ user.role }}</p>
        </div>
      </div>

      <p class="text-xs text-neutral">
        User and theme are read from a <strong>headless</strong> component
        via <code class="bg-base-300 px-1 py-0.5 rounded">useLiveVue("shared-state")</code>.
        No props passed directly — all shared state comes from the headless provider.
      </p>
    </div>
  </div>
</template>

How it works

1 Render a headless component with just an id

A <.vue> without v-component renders nothing visually but registers its props under the given id. In a real app, this lives in a sticky LiveView so it persists across page navigation.

<.vue id="shared-state" v-socket={@socket} user={@user} theme={@theme} />

2 Read shared props with useLiveVue(id)

Any Vue component on the page can call useLiveVue("shared-state") to access the headless component's props reactively. No prop drilling required.

const shared = useLiveVue("shared-state")
const user = computed(() => shared?.vue.props.user)

3 Server changes propagate automatically

When the server updates assigns on the headless component (e.g. switching user or theme), all consumers that read via useLiveVue() re-render with the new values. Try toggling theme or switching users above.

Explore more examples
View all examples