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
shared_props_live.ex
defmodule MyAppWeb.SharedPropsLive do
  use MyAppWeb, :live_view

  @users [
    %{name: "Alice", role: "Engineer"},
    %{name: "Bob", role: "Designer"},
    %{name: "Carol", role: "Product Manager"}
  ]

  def render(assigns) do
    ~H"""
    <div class="space-y-4">
      <.vue
        id="shared-state"
        v-socket={@socket}
        user={@user}
        theme={@theme}
      />

      <.vue
        v-component="SharedProps"
        v-socket={@socket}
        pageTitle="Dashboard"
      />

      <div class="flex gap-2">
        <button phx-click="toggle_theme" class="btn btn-sm btn-outline">
          Toggle theme
        </button>
        <button phx-click="cycle_user" class="btn btn-sm btn-outline">
          Switch user
        </button>
      </div>
    </div>
    """
  end

  def mount(_params, _session, socket) do
    {:ok, assign(socket, theme: "light", user: hd(@users), user_index: 0)}
  end

  def handle_event("toggle_theme", _params, socket) do
    theme = if socket.assigns.theme == "light", do: "dark", else: "light"
    {:noreply, assign(socket, :theme, theme)}
  end

  def handle_event("cycle_user", _params, socket) do
    index = rem(socket.assigns.user_index + 1, length(@users))
    {:noreply, assign(socket, user: Enum.at(@users, index), user_index: index)}
  end
end

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