Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

SquareNetMedia's avatar

Livewire and Pusher

I think I am missing something really obvious but cannot see what I am over looking.

I am using Larvael 9, Livewire and Pusher.

I have a Form which allows the user to Post a comment which I am wanting to update for everyone in real time. Everything seems to be working as I can see the Post ID when I DD after the event but for some reasons I cannot get the posts to refresh automaticaly so it shows up without refreshing the brower.

I have the following code

Event

namespace App\Events;

use App\Models\Post;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;



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

    public $id;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(Post $post)
    {
        //
        $this->id = $post->id;

    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new Channel('posts');
    }

}

The Livewire Post Component (To View All Posts)

namespace App\Http\Livewire;

use App\Models\Post;
use Livewire\Component;

class Posts extends Component
{
    public $posts;


    // Special Syntax: ['echo:{channel},{event}' => '{method}']
    protected $listeners = ['echo:posts,PostCreated' => 'prependPost'];


    public function mount()
    {
        $this->posts = Post::latest()->get();
        
    }

    public function UpdatePost($post)
    {
        dd($post);  //Shows the Post ID

    }

    public function render()
    {
        
        return view('livewire.posts', [

            $this->posts = Post::latest()->get()
        ]);
    }
}

Post Form (Livewire Component)

namespace App\Http\Livewire;

use Livewire\Component;
use App\Events\PostCreated;
use Illuminate\Support\Facades\Auth;

class PostForm extends Component
{
    public $body = '';

    protected $rules = [
        'body' => 'required',
    ];

    public function storePost()
    {
        $this->validate();

        $post = Auth::user()->posts()->create([
            'body' => $this->body,
        ]);

        //$this->emit('PostCreated', $post);
        event(new PostCreated($post));

       // broadcast(new PostCreated($posts));

        $this->body = '';
    }



    public function render()
    {
        return view('livewire.post-form');
    }
}

Any help would be appreciated :-)

1 like
8 replies
vincent15000's avatar

Have you open your app simultanuously in two different browsers to test it ?

Snapey's avatar

show your javascript that listens for the broadcast and fires an event to Livewire?

1 like
SquareNetMedia's avatar

@Snapey

Is that what I could be missing as I just have the standard details in the js to connect to pusher which is

import Echo from 'laravel-echo';

import Pusher from 'pusher-js';
window.Pusher = Pusher;

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: import.meta.env.VITE_PUSHER_APP_KEY,
    cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER ?? 'mt1',
    wsHost: import.meta.env.VITE_PUSHER_HOST ? import.meta.env.VITE_PUSHER_HOST : `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
    wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
    wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
    forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
    enabledTransports: ['ws', 'wss'],

});
1 like
Snapey's avatar

@SquareNetMedia yes. In the other clients you have receive the broadcast event with echo and then fire Livewire event to the local Livewire javascript which will message the backend to update the view.

If you have a lot of clients online, bear in mind that they will all fire the same queries at the same time, so consider caching

1 like
arapchirchir's avatar

Dispatching an event in livewire controller

PostCreated::dispatch($room);

in PostCreated Event public function __construct(public $room) {}

/**
 * Get the channels the event should broadcast on.
 *
 * @return array<int, \Illuminate\Broadcasting\Channel>
 */
public function broadcastOn()
{
    return new PrivateChannel('room-' . $this->room->id); //if it's private
}


public function broadcastAs()
{
    return 'group.message.sent';
}

Listen for the event public function getListeners() { return [ "echo-private:room-{$room->id},.group.message.sent" => 'notifyUser', ]; }

public function notifyUser($data)
{
    dd($data);
}

in channels.php

Broadcast::channel('room-{id}', function ($user, $id) { return true; });

NB make sure that if you have used (-) be consistent with it dont mix (-) and (.)

Exampl above I have used (-)

1 like

Please or to participate in this conversation.