php 50 lines · 9 steps

Broadcasting typing indicators in Laravel

A controller authorizes a request, then broadcasts a real-time typing event to everyone else on a conversation's presence channel.

Explained by highlit
1<?php
2 
3namespace App\Http\Controllers;
4 
5use App\Models\Conversation;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8use Illuminate\Support\Facades\Broadcast;
9 
10class TypingIndicatorController extends Controller
11{
12 public function store(Request $request, Conversation $conversation): JsonResponse
13 {
14 $this->authorize('view', $conversation);
15 
16 $validated = $request->validate([
17 'is_typing' => ['required', 'boolean'],
18 ]);
19 
20 $user = $request->user();
21 
22 Broadcast::on("presence-conversation.{$conversation->id}")
23 ->as('client-typing')
24 ->with([
25 'user' => [
26 'id' => $user->id,
27 'name' => $user->name,
28 'avatar' => $user->avatar_url,
29 ],
30 'is_typing' => $validated['is_typing'],
31 'at' => now()->toIso8601String(),
32 ])
33 ->toOthers()
34 ->sendNow();
35 
36 return response()->json(status: 202);
37 }
38}
39 
40Broadcast::channel('conversation.{conversation}', function ($user, Conversation $conversation) {
41 if (! $conversation->participants()->whereKey($user->id)->exists()) {
42 return false;
43 }
44 
45 return [
46 'id' => $user->id,
47 'name' => $user->name,
48 'avatar' => $user->avatar_url,
49 ];
50});
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Presence channels let you broadcast ephemeral events like typing state without persisting them to a database.
  2. 2Returning attributes from a channel authorization callback both authorizes the user and shares their profile with other members.
  3. 3toOthers() and a 202 status keep the sender's own UI in sync while acknowledging a fire-and-forget event.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Broadcasting typing indicators in Laravel — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code