LiveVue 1.1
Examples v-inject

v-inject

v1.1

Inject a Vue component into another component's slot — even when they're rendered by different LiveViews. The layout component persists while only the page content changes.

What this example shows

1
Layout Component
Rendered with an id, owns the slot
2
Slot Injection
v-inject targets the layout by id
3
Independent Updates
Layout and page update separately
InjectLayout.vue
<script setup lang="ts">
defineProps<{
  title: string
  theme: string
}>()
</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'"
  >
    <!-- Layout header -->
    <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'"
    >
      <div class="flex items-center gap-2">
        <div class="w-2.5 h-2.5 rounded-full bg-error"></div>
        <div class="w-2.5 h-2.5 rounded-full bg-warning"></div>
        <div class="w-2.5 h-2.5 rounded-full bg-success"></div>
      </div>
      <span class="text-sm font-medium">{{ title }}</span>
      <span class="text-xs px-2 py-0.5 rounded-full bg-secondary/20 text-secondary">
        {{ theme }}
      </span>
    </div>

    <!-- Slot for injected page content -->
    <div class="p-6">
      <slot>
        <p class="text-neutral italic text-sm">No page injected</p>
      </slot>
    </div>
  </div>
</template>

How it works

1 Render a layout component with an id

The layout component is rendered with a unique id. It defines a <slot /> where page content will be injected. In a real app, this would typically live in root.html.heex or a sticky LiveView.

<.vue id="app-layout" v-component="AppLayout" v-socket={@socket} title="My App" />

2 Inject a page into the layout's slot

The page component uses v-inject="app-layout" to target the layout by its id. The page is rendered inside the layout's default slot instead of inline.

<.vue v-component="Page" v-inject="app-layout" v-socket={@socket} message={@message} />

3 Layout and page update independently

Toggle the theme — only the layout re-renders. Change the message — only the page updates. In a real app with a sticky LiveView layout, the layout Vue component persists across LiveView navigation while pages swap in and out of the slot.

Next up: Headless Shared Props
View example →