• Reading time ~ 5 min
  • 10.10.2023

Laravel Volt

Tony Lea

Laravel Volt is a new package that was announced during Laracon 2023. Volt brings the power of single file Livewire components to Laravel and it works seamlessly with Folio.Similar to how React and Vue developers can write single-file components, Laravel Volt brings single-file components to blade templates. This will allow developers to create powerful and interactive components that leverage the back-end and the front-end.

Creating Components

You can easily create a new Volt Component by running:

php artisan make:volt counter

This will create a new file in the resources/views/livewire directory called counter.blade.php, with the following contents:

<?php

use function Livewire\Volt\{state};

//

?>

<div>
    //
</div>

We can add a little bit of code to get our counter component working:

<?php

    use function Laravel\Volt\{state};
    state(['currentValue' => 0]);

    $increment = fn () => $this->currentValue++;
?>

<div> 
    <div>current Value: {{ $currentValue }}</div>
    <button class="mt-2" wire:click="increment">
        Increment
    </button>
</div>

Next, we can create a new Folio page to render our new component:

artisan make:folio volt

This will generate a new Folio page located at resources/views/pages/volt.blade.php. We can add the following code:

<x-layout>
    <div class="mt-6">
        <livewire:counter />
    <div>
</x-layout>

And, just as simple as that we have a simple counter component in our application.

volt counter example
Notice that this is not just a front-end counter. The variable $currentValue is a value stored in the back-end. This means that you can easily share data between your front-end and back-end with ease 🎉

Volt State

As you can see from above, Volt gives us the ability to easily manage state by utilizing the use function Laravel\Volt\{state}; declaration.

After defining the {state} declaration we now have access to the state helper method which we can use to set state for any of our variables:

<?php

    use function Laravel\Volt\{state};
    state(['currentValue' => 0]);

?>

Now, we will have access to the $currentValue variable inside of the template, and thanks to the power of Livewire and AlpineJS we can keep track of the state of any variables on the front-end and the back-end.

Volt Provide

We may also want to provide our template with some data; however, we don't specifically want to share the state of the data between the front-end and the back-end. To do this we can take advantage of the {provide} declaration:

<?php
    use App\Models\Todo;
    use function Laravel\Volt\{provide};

    provide (fn () => [
        'todos' => Todo:: all (),
    ]);
?>
<div>
    @foreach($todos as $todo)
        <!-- output the $todo data -->
    @endforeach
</div>

Now, inside of our template we will be able to access the $todos variable which will contain a collection of Todos that we've fetched from the database.

You may want to use {provide} and {state} in the same component, which can easily be accomplished with the following code:

<?php
    use App\Models\Todo;
    use function Laravel\Volt\{provide, state};
    
    state(['title' => '']);
    
    provide(fn () => [
        'todos' => Todo:: all (),
    ]);
?>

Now our template will have all the $todos data available and we will share state with a variable called $title.

Volt Functions

Defining functions to be used in your Volt components is very easy. Here's an example of how we can create a function to add a new todo item to our database:

<?php
    use App\Models\Todo;
    use function Laravel\Volt\{provide, state};
    
    state(['title' => '']);
    
    provide(fn () => [
        'todos' => Todo:: all (),
    ]);

    $add = function () {
        Todo:: create([
            'title' => $this-›title,
        ]);

        $this->title = ":
    };
?>

<div> 
    <form wire:submit.prevent="add"> 
        <input name="title" wire:model="title" />
        <button type="submit">Add Todo</button>
    </form>
</div>

In the code above when the form is submitted it will call the $add method and create the new todo in the database and clear out the title. Pretty cool 😎

Volt Validation Rules

You can also add validation to your Volt components really easily. Here's an example of how we can validate that the $title variable is not empty and has a minimum of at-least three characters.

<?php
    use App\Models\Todo;
    use function Laravel\Volt\{provide, rules, state};
    
    state(['title' => '']);

    rules(['title' => 'required|min:3']);
    
    provide(fn () => [
        'todos' => Todo:: all (),
    ]);

    $add = function () {
        Todo:: create([
            'title' => $this-›title,
        ]);

        $this->title = ":
    };
?>

<div> 
    <form wire:submit.prevent="add"> 
        <input name="title" wire:model="title" />
        <button type="submit">Add Todo</button>
    </form>
    @error ('title')
        <span class="text-red-500">{{ $message }}</span>
    @enderror
</div>

You'll see that above we've added a new {rules} declaration that gives us access to the rules() helper method allowing us to add validation to any state in our volt component.

Conclustion

Be sure to learn more about installation and additional functionality by checking out the Volt documentation at https://livewire.laravel.com/docs/volt.

Volt will help us build dynamic and interactive user interfaces without the need for separate files. Volt gives us code colocation, bringing the behavior and markup of components together in a single file for enhanced productivity. Electrifying stuff ⚡️

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

ABOUT

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

About author CrazyBoy49z
WORK EXPERIENCE
Contact
Ukraine, Lutsk
+380979856297