Livewire: Using wire:stream for Real-Time Updates

Published on May 25, 2024. Last updated on January 22, 2025.
Livewire: Using wire:stream for Real-Time Updates

This post will guide you through using wire:stream in Livewire. Explore its versatility for features such as ChatGPT API streaming and more.

We use Livewire's wire:stream in an Addon System to indicate the current installation step (e.g., conducting requirement checks, registering hooks, etc.) in our Applications. We're eager to share our insights and experiences with this implementation.

Livewire's stream feature utilizes Server-Sent Events (SSE) under the hood. If you're unfamiliar with SSE and would like to learn more, you can find detailed information on MDN.

We assume you already have a Livewire component. To stream the installation log when the user clicks the "Install Addon" button, follow these steps.

<div>
    <div wire:stream="installLog"></div>
    <button type="button" wire:click="install">Install Addon</button>
</div>

As shown, the installation button triggers the install method upon click. At the top, there's a div  with the wire:stream attribute set to installLog, which corresponds to the stream name we want to display.

In this example, we'll simulate real-world delays by using the sleep function to delay the output.

public function install(): void
    {
        $steps = [
            'Checking requirements',
            'Running Database Migrations',
            'Registering Hooks',
            'Cleaning Cache',
            'Installation completed',
        ];

        foreach ($steps as $step) {
            $this->stream(
                to: 'installLog',
                content: $step .'<br>',
                replace: false
            );

            sleep(1); // simulate delay
        }
    }

 

 

It works fine. However, we want the install log to persist after the stream is completed. To achieve this, we need to save the install log in a property and use it inside the wire:stream div.

Please update your template as follows:

<div>
    <div wire:stream="installLog">
        {!! $log !!}
    </div>
    <button type="button" wire:click="install">Install Addon</button>
</div>

Please update your component class as follows:

//...
public $log = '';

public function install(): void
    {
        $steps = [
            'Checking requirements',
            'Running Database Migrations',
            'Registering Hooks',
            'Cleaning Cache',
            'Installation completed',
        ];

        foreach ($steps as $step) {
            $this->stream(
                to: 'installLog',
                content: $step .'<br>',
                replace: false
            );
           $this->log .= $step .'<br>';

            sleep(1); // simulate delay
        }
    }

 

From now on, the $log will be displayed after the stream has completed. This is a basic example of how you can implement the wire:stream feature.