Real-time streaming in Laravel Livewire 4: Ideal for AI chatbots

Real-Time Streaming in Laravel Livewire 4 IDEAL for AI Chatbots

There is an extremely powerful use case available in Livewire: Streaming. To understand it simply, we provide the following concept:

Streaming is a technology that allows the distribution of large volumes of data (video, audio, video games, or text) in a way that the user can start consuming the content before the download is complete.

You are likely already familiar with this without knowing it. When you watch a video on YouTube or Netflix, you don't need to download the 2 GB of the movie to start watching it; the player processes the data as it arrives.

Streaming in Artificial Intelligence

Today, the clearest example is in AIs like ChatGPT or Gemini. When you ask a question, the answer doesn't appear all at once after a 10-second wait (the traditional 0% to 100% scheme). Instead, we see how the AI writes word by word in real time. That is streaming: consuming the result while the task is still being processed.

Implementation in Livewire 4

In modern Livewire, using this technology is surprisingly straightforward. Let's ground this with a simple exercise: a counter that reduces its value every second.

The Traditional Scheme (Without Streaming)

If we use a normal function with a while loop and a sleep(1), the browser will hang while "thinking". The user will see the initial number (for example, 3) and, after three seconds of waiting, the final number (-1) will appear ALL AT ONCE. All intermediate progress is lost.

resources\views\pages\stream\⚡count-down.blade.php

<?php
use App\Ai\Agents\PokemonAgent;
use Laravel\Ai\Streaming\Events\TextDelta;
use Livewire\Component;
 
new class extends Component
{
    public $start = 3;
 
    public function begin()
    {
        while ($this->start >= 0) {
 
            // Pause for 1 second between numbers...
            sleep(1);
 
            // Decrement the counter...
            $this->start = $this->start - 1;
        };
    }
}
?>
<div>
    <flux:button wire:click="begin">Start count-down</flux:button>
    <h1 class="text-center mt-4">Count: <span>{{ $start }}</span></h1> 
</div>

The Streaming Scheme

To enable real-time progress, we use the stream() method. Here are the key elements of the magic:

$this->stream(  
   to: 'count',
   content: $this->start,
   replace: true,
);
  • The identifier (to): You must associate the stream with an HTML element. For example, a <span> with an ID or a reference.
  • The content (content): This is the data we are sending in each iteration of the loop.
  • The action (replace) OPTIONAL: By default, streaming might concatenate data. By using replace: true, we indicate that each new piece of data should replace the previous one, creating the effect of an updating counter.

resources\views\pages\stream\⚡count-down.blade.php

<?php
use App\Ai\Agents\PokemonAgent;
use Laravel\Ai\Streaming\Events\TextDelta;
use Livewire\Component;
 
new class extends Component
{
    public $start = 3;
 
    public function begin()
    {
        while ($this->start >= 0) {
            // Stream the current count to the browser...
            $this->stream(  
                to: 'count',
                content: $this->start,
                replace: true,
            );
 
            // Pause for 1 second between numbers...
            sleep(1);
 
            // Decrement the counter...
            $this->start = $this->start - 1;
        };
    }
}
?>
<div>
    <flux:button wire:click="begin">Start count-down</flux:button>
    <h1 class="text-center mt-4">Count: <span wire:stream="count">{{ $start }}</span></h1> 
</div>

When executing the previous exercise, you will see that 3 2 1 0 -1 now appears on the screen—that is, the INTERMEDIATE steps.

Streams are a key technology, just like HTTP, WebSockets, etc., and they are used ENORMOUSLY in modern development (in the projects section, we show a use case with an AI agent).

The "Strange" thing about Streaming: Properties vs. Content

A detail that might seem abstract is what value is actually displayed on the screen.

  • Start and End: At the beginning and end of the function, the component displays the actual value of the property defined in the class (the classic Livewire state).
    • public $start = 3;
  • During the process: While the stream flow is active, what you see in the browser is the content you manually send through the stream method:
    • content: $this->start,

It's as if, for a moment, the browser ignores the variable's value and only listens to what the "stream" of data sends it. Therefore, if you add an arbitrary value to the content (like a +10), you will see that number on the screen even though the counter's internal property remains different.

Real Applications: Chatbots and Assistants

This technology is the current standard for building virtual assistants. In the projects section of the book, we will develop a Chatbot similar to Gemini. We will see how, when asking a question, the assistant starts rendering fragments of the response as the API generates them.

Without streaming, the user experience would be frustrating, forcing long waits in front of a loading screen. With this, we add dynamism and a sense of immediate response to our applications.

Discover how to use Stream technology in Livewire 4 to send data to the browser before the task is completed.

I agree to receive announcements of interest about this Blog.

Andrés Cruz

ES En español