Laravel Reverb: make a chatbox component for your site!
Tags: laravel, php
Published: 2024-04-03 22:31:25

Laravel 11 was released a few weeks ago and with it is laravel reverb, a first-party websocket package to help with real-time applications.
In this article I'll demonstrate how to make a simple chatbox component for support-related purposes...

first off we'll create a new laravel application using laravel new

```
laravel new chatbox
cd chatbox
```

then after all installation is complete we can use the new command to install laravel reverb

```
php artisan install:broadcasting
```
make sure the .env file has this line set to sync

```
QUEUE_CONNECTION=sync
```
next all we have to do is to create an event and listen on its channel

```
php artisan make:event MessageSent
```
and make it look something like this

```
<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class MessageSent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * Create a new event instance.
     */
    public function __construct( public string $name, public string $text)
    {
        //
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return array<int, \Illuminate\Broadcasting\Channel>
     */
    public function broadcastOn(): array
    {
        return [
            new Channel('messages'),
        ];
    }
}
```
next we create the livewire component to listen on the channel

```
php artisan make:volt ChatBox --class
```
and make it like so...

```
<?php
use App\Events\MessageSent;
use Livewire\Volt\Component;
new class extends Component
{
    /**
     * @var string[]
     */
    public array $messages = [];
    public string $message = '';
    protected $listeners = ['echo:messages,MessageSent' => 'onMessageSent'];
    public function addMessage()
    {
        MessageSent::dispatch(auth()->user()->name, $this->message);
        $this->reset('message');
    }
    #[On('echo:messages,MessageSent')]
    public function onMessageSent($event)
    {
        $this->messages[] = $event;
    }
}
?>

<div x-data="{ open: true }" >
    <div :class="{'-translate-y-0': open, 'translate-y-full': !open}" class="fixed transition-all duration-300 transform bottom-10 right-12 h-60 w-80">
        <div class="mb-2">
            <button @click="open = !open" type="button" :class="{ 'text-indigo-600 dark:text-white hover:bg-transparent': open }" class="w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-white rounded-lg hover:bg-indigo-400 dark:bg-indigo-600 dark:hover:bg-indigo-400">
                Chat

                <x-heroicon-o-chevron-up x-show="!open" x-cloak class="ms-auto block size-4" />
                <x-heroicon-o-chevron-down x-show="open" x-cloak class="ms-auto block size-4" />

            </button>
        </div>
        <div class="w-full h-full bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded overflow-auto flex flex-col px-2 py-4">
            <div x-ref="chatBox" class="flex-1 p-4 text-sm flex flex-col gap-y-1">
                @foreach($messages as $message)
                    <div><span class="text-indigo-600">{{ $message['name'] }}:</span> <span class="dark:text-white">{{ $message['text'] }}</span></div>
                @endforeach
            </div>
            <div>
                <form wire:submit.prevent="addMessage" class="flex gap-2">
                    <x-text-input wire:model="message" x-ref="messageInput" name="message" id="message" class="block w-full" />
                    <x-primary-button>
                        Send
                    </x-primary-button>
                </form>
            </div>
        </div>
    </div>
</div>
```
next we add it anywhere to the welcome page of the default laravel, and we need to start the reverb server...

```
php artisan serve
```
and on another terminal
```
php artisan reverb:start
```
and we are all set!
the chatbox should be working and all should be complete