Creating Vue component inside Laravel Livewire

Topics: Laravel, Livewire, Vue on Apr 3, 2025

Getting started

So I love working with Livewire for backend-heavy stuff and rapid prototyping, but sometimes, let's be honest — there are things Vue does better. Like if you need a super reactive or animated component.

In this tutorial I’ll show you how I added Vue to a Laravel project that uses Livewire, without breaking anything 🚀


First, install Laravel with Livewire

If you don’t have it already, let’s start fresh:

laravel new livewire-vue-demo
cd livewire-vue-demo
composer require livewire/livewire
php artisan livewire:publish

Let’s add a simple Livewire component to make sure it's working:

php artisan make:livewire Counter

Now inside resources/views/livewire/counter.blade.php:

<div>
    <button wire:click="increment">+</button>
    <h1>{{ $count }}</h1>
</div>

And in the class:

public $count = 0;

public function increment()
{
    $this->count++;
}

Now Livewire is working. Time to Vue it up.


Add Vue to the mix

Install Vue (we're gonna use it via Vite):

npm install vue

Now go to your resources/js/app.js file and add:

import { createApp } from 'vue'

import Example from './components/Example.vue'

const app = createApp({})
app.component('example', Example)
app.mount('#vue-root')

Create your Vue component

Inside resources/js/components, create a new file: Example.vue

<template>
  <div>
    <h2>This is Vue inside Livewire</h2>
    <input v-model="message" placeholder="Type something..." />
    <p>You typed: {{ message }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue'
const message = ref('')
</script>

Add it to your Blade view

Now here’s the trick — we want to render Vue inside a Livewire view, but they shouldn’t conflict. Vue needs its own root element.

So inside counter.blade.php (or wherever):

<div>
    <button wire:click="increment">+</button>
    <h1>{{ $count }}</h1>

    <div id="vue-root">
        <example></example>
    </div>
</div>

Make sure this #vue-root is outside of any Livewire-controlled part you want to update reactively, or Livewire might re-render and destroy your Vue app 😅


Compile and go

Run the build:

npm run dev

Visit the page and you should see your Livewire counter and Vue component living in peace together 🕊️


Real-world tip

If you want to pass data from Laravel/Livewire to Vue, you can do it like this:

<div id="vue-root" data-name="{{ $user->name }}">
    <example :name="document.getElementById('vue-root').dataset.name"></example>
</div>

Or use Alpine to pass props directly.


TL;DR

  • Livewire and Vue can work together if you separate their concerns.
  • Mount Vue manually with createApp() on a safe DOM ID.
  • Don't put Vue inside Livewire dynamic parts unless you're OK with re-renders.
  • Great for charts, inputs, animations, modals... anything dynamic.