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

Nabisalay's avatar

Broadcasting using Laravel Reverb with react inertia

Actually I am learning inertia and everything was working fine i followed the chirp tutorial of bootcamp.laravel.com and i have successfully created a SPA chat application but now the problem is this that I'm tryin to add real time communication using laravel reverb but don't really know how can I implement the functionality with inertia react.

This is the code of controller

<?php

namespace App\Http\Controllers;

use App\Models\Message;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class MessageController extends Controller
{
public function index(): Response
    {
        //
        return Inertia::render('Application/Index', [
            'chats' => Message::with('user:id,name')->latest()->get(),
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        //
        $validate = $request->validate([
            'message' => ['required', 'string', 'max:255'],
        ]);
        $request->user()->messages()->create($validate);

        return redirect(route('messages.index'));
    }
}

Here is the message component

import React from "react";

export default function Message({ chat }) {
    return (
        <div className="p-6 flex space-x-2">
            <svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 text-gray-600 -scale-x-100" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2">
                <path strokeLinecap="round" strokeLinejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
            </svg>
            <div className="flex-1">
                <div className="flex justfify-between items-center">
                    <span className="text-gray-800">{chat.user.name}</span>
                    <small className="ml-2 text-sm text-gray-600">
                        {new Date(chat.created_at).toLocaleString()}
                    </small>
                </div>
            </div>
            <p className="mt-4 text-lg text-gray-900">
                {chat.message}
            </p>
        </div>
    );
}

and here is the Index component

import React from "react";
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout";
import Message from "@/Components/Message";
import InputError from "@/Components/InputError";
import PrimaryButton from "@/Components/PrimaryButton";
import { useForm, Head } from "@inertiajs/react";

export default function Index({ auth, chats }) {
    const { data, setData, post, processing, reset, errors } = useForm({
        message: "",
    });
    const submit = (e) => {
        e.preventDefault();
        post(route("messages.store"), { onSuccess: () => reset() });
    };
    return (
        <AuthenticatedLayout
            user={auth.user}
            header={
                <h2 className="font-semibold text-xl text-gray-800 leading-tight">
                    My Chat
                </h2>
            }
        >
            <Head title="Chat" />
            <div className="max-w-2xl space-y-5 mx-auto p-4 sm:p-6 lg:p-8">
                <div className="h-full flex flex-col overflow-auto bg-white shadow-sm rounded-lg divide-y">
                    {chats.map((chat) => (
                        <Message key={chat.id} chat={chat} />
                    ))}
                </div>
                <div>
                <form onSubmit={submit} className="bottom-0 bg-white shadow-sm rounded-b-lg">
                    <div className="flex space-x-4">
                    <textarea
                        value={data.message}
                        placeholder="Type your message...."
                        className="block w-full border-gray-300 focus:border-indigo-300 focus:ring-opacity-50 rounded-md shadow-sm"
                        onChange={(e) => setData("message", e.target.value)}
                    ></textarea>
                    <InputError message={errors.message} className="mt-2" />
                    <PrimaryButton className="mt-4" disabled={processing}>
                        Send
                    </PrimaryButton>
                    </div>
                </form>
                </div>
            </div>
        </AuthenticatedLayout>
    );
}

Any guidance would be really valuable and if need any further information please let me know. Thanks for your time and consideration.

0 likes
6 replies
Nabisalay's avatar

Thanks buddy it worked this is how I used it

export default function Index({ auth, chats }) {
    const { data, setData, post, processing, reset, errors } = useForm({
        message: "",
    });
const [allMessages, setAllMessages] = useState(messages);
    useEffect(() => {
        const channel = window.Echo.channel("chat");
        channel.listen("SendMessageEvent", (newMessage) => {
            setAllMessages((prevAllMessages) => [
                ...prevAllMessages,
                newMessage.newMessage,
            ]);
        });
        return () => {
            channel.unsubscribe();
        };
    }, []);
    const submit = (e) => {
        e.preventDefault();
        post(route("messages.store"), { onSuccess: () => reset() });
    };
}
// this are all the message
        <div className="flex flex-col space-y-2">
            {allMessages.map(message =>
              <Message key={message.id} message={message} auth={auth}/>
            )}            
        </div>

It works fine now

Nabisalay's avatar

@gych Got one more problem the code is working fine but when I come to the route for the first time and type some messages. It doesn't appear on the screen. Whereas, they have been storing in the database successfully and when I refresh the page and send the message they can be seen easily on the screen in the real time of both sender and receiver browser but again if I switch the route and come back again to the chat route then same problem. Tried to debug but wasn't able to. May be problem is related to the initial render and the way i am using useEffect. It would be really great if any one can help to figure out how this can be solved.

export default function Index({ auth, chats }) {
    const { data, setData, post, processing, reset, errors } = useForm({
        message: "",
    });
const [allMessages, setAllMessages] = useState(messages);
    useEffect(() => {
        const channel = window.Echo.channel("chat");
        channel.listen("SendMessageEvent", (newMessage) => {
            setAllMessages((prevAllMessages) => [
                ...prevAllMessages,
                newMessage.newMessage,
            ]);
        });
        return () => {
            channel.unsubscribe();
        };
    }, []);
    const submit = (e) => {
        e.preventDefault();
        post(route("messages.store"), { onSuccess: () => reset() });
    };
}
// this are all the message
        <div className="flex flex-col space-y-2">
            {allMessages.map(message =>
              <Message key={message.id} message={message} auth={auth}/>
            )}            
        </div>
DYS's avatar
window.Echo.channel("price").listen('PackageSent', (e) => {
        console.log("create listen.", e);
        console.log(e.event);
        
    });

the console.log can't print log . Why ?

DYS's avatar

I finally fixed it . document link is : stackoverflow.com/questions/76506585/laravel-echo-pusherjs-callback-function-not-working

Please or to participate in this conversation.