Skip to content

Add Laravel broadcasting support (Reverb, Pusher, Ably) - #23

Open
limonte with Copilot wants to merge 6 commits into
mainfrom
copilot/add-laravel-broadcasting-support
Open

Add Laravel broadcasting support (Reverb, Pusher, Ably)#23
limonte with Copilot wants to merge 6 commits into
mainfrom
copilot/add-laravel-broadcasting-support

Conversation

Copilot AI commented May 9, 2026

Copy link
Copy Markdown
Contributor

Real-time SweetAlert2 popups from the backend without a page reload — useful for actions like sending emails from a dashboard, completing background jobs, or any server-side event that shouldn't navigate the user.

Backend

New static methods on Swal dispatch a SweetAlert2BroadcastEvent (ShouldBroadcastNow) via Laravel's broadcasting system:

// Public channel
Swal::broadcast('my-channel', ['title' => 'Email sent!', 'icon' => 'success']);
Swal::broadcastToastSuccess('my-channel', ['title' => 'Done!']);

// Private channel (e.g. per-user)
Swal::broadcastPrivate('user.' . $user->id, ['title' => 'Your report is ready.', 'icon' => 'info']);
Swal::broadcastPrivateToastSuccess('user.' . $user->id, ['title' => 'Saved!']);

Full set of icon/toast shortcuts mirrors the existing Swal::fire() / Swal::success() / Swal::toastSuccess() API for both public and private channels.

Frontend

A new blade partial subscribes to the channel via Laravel Echo and fires Swal.fire() on receipt. Uses the same callback validation + XSS sanitisation as the existing Livewire/Inertia templates.

{{-- in your layout, requires window.Echo to be configured --}}
@include('sweetalert2::broadcast', ['channel' => 'my-channel'])

{{-- private channel --}}
@include('sweetalert2::broadcast', ['channel' => 'user.' . auth()->id(), 'private' => true])

Key implementation details

  • SweetAlert2BroadcastEvent implements ShouldBroadcastNow (sync, no queue required); broadcasts as sweetalert2-message — the existing SESSION_KEY constant — so Echo listens with .sweetalert2-message
  • resources/views/shared/ is registered as a secondary view path under the sweetalert2 namespace, so sweetalert2::broadcast resolves while sweetalert2::index continues to resolve from the context-specific path (livewire/inertia/laravel)
  • Works with any broadcasting driver (Reverb, Pusher, Ably); no hard dependency added

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/doctrine/inflector/zipball/6d6c96277ea252fc1304627204c3d5e6e15faa3b
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/jZph7v /usr/bin/composer global require laravel/installer (http block)
  • https://api.github.com/repos/illuminate/collections/zipball/17b082d0c66fb030f22d5bdd62ba652c045ff522
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/illuminate/conditionable/zipball/7f1ef52d9a346f829421b296adfb7644a951b216
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/jZph7v /usr/bin/composer global require laravel/installer (http block)
  • https://api.github.com/repos/illuminate/contracts/zipball/ce6f5561f88743639c76835ad82cfe39b468bdc8
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/jZph7v /usr/bin/composer global require laravel/installer (http block)
  • https://api.github.com/repos/illuminate/macroable/zipball/59b5b5f3cf290a91db8cf6cd3d35ff56978bc057
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/jZph7v /usr/bin/composer global require laravel/installer (http block)
  • https://api.github.com/repos/illuminate/reflection/zipball/4fe1659f068ab2b50131cf906c5d8bba4e34df0c
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/jZph7v /usr/bin/composer global require laravel/installer (http block)
  • https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/jZph7v /usr/bin/composer global require laravel/installer (http block)
  • https://api.github.com/repos/symfony/polyfill-php84/zipball/88486db2c389b290bf87ff1de7ebc1e13e42bb06
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/polyfill-php85/zipball/fcfa4973a9917cef23f2e38774da74a2b7d115ee
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/jZph7v /usr/bin/composer global require laravel/installer (http block)
  • https://api.github.com/repos/symfony/polyfill-php86/zipball/33d8fc5a705481e21fe3a81212b26f9b1f61749c
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/jZph7v /usr/bin/composer global require laravel/installer (http block)
  • https://api.github.com/repos/symfony/process/zipball/60f19cd3badc8de688421e21e4305eba50f8089a
    • Triggering command: REDACTED, pid is -1 (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI linked an issue May 9, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Add Laravel broadcasting implementation for real-time notifications Add Laravel broadcasting support (Reverb, Pusher, Ably) May 9, 2026
Copilot AI requested a review from limonte May 9, 2026 15:53
Copilot finished work on behalf of limonte May 9, 2026 15:53
@limonte
limonte marked this pull request as ready for review May 9, 2026 16:31
@limonte

limonte commented May 10, 2026

Copy link
Copy Markdown
Member

@copilot tests are failing

…atisfy strict return type

Agent-Logs-Url: https://github.com/sweetalert2/sweetalert2-laravel/sessions/cc463190-b66e-46f8-a760-0678c5e1c076

Co-authored-by: limonte <6059356+limonte@users.noreply.github.com>

Copilot AI commented May 10, 2026

Copy link
Copy Markdown
Contributor Author

@copilot tests are failing

Fixed in a2559ab. The recording broadcaster stub's event() was declared void, but Laravel's broadcast() helper enforces a strict PendingBroadcast return type — causing the TypeError. The stub now returns a PendingBroadcast wrapping a no-op event dispatcher, so the return type is satisfied and no real broadcast is sent.

@limonte

limonte commented May 10, 2026

Copy link
Copy Markdown
Member

@copilot 2 tests are still failing:

 FAILED  Tests\Feature\BroadcastTest > broadcast view uses window.Echo.cha…   
  Expecting '<script type="module">con…ipt>' not to contain 'window.Echo.private'.

  at tests/Feature/BroadcastTest.php:60
     56▕     $rendered = view('sweetalert2::broadcast', ['channel' => 'announcements'])->render();
     57▕ 
     58▕     expect($rendered)
     59▕         ->toContain('window.Echo.channel("announcements")')
  ➜  60▕         ->not->toContain('window.Echo.private');
     61▕ });
     62▕ 
     63▕ test('broadcast view uses window.Echo.private() for a private channel', function () {
     64▕     $rendered = view('sweetalert2::broadcast', ['channel' => 'user.1', 'private' => true])->render();

  1   tests/Feature/BroadcastTest.php:60

  ────────────────────────────────────────────────────────────────────────────  
   FAILED  Tests\Feature\BroadcastTest > broadcast view uses window.Echo.pri…   
  Expecting '<script type="module">con…ipt>' not to contain 'window.Echo.channel'.

  at tests/Feature/BroadcastTest.php:68
     64▕     $rendered = view('sweetalert2::broadcast', ['channel' => 'user.1', 'private' => true])->render();
     65▕ 
     66▕     expect($rendered)
     67▕         ->toContain('window.Echo.private("user.1")')
  ➜  68▕         ->not->toContain('window.Echo.channel');
     69▕ });
     70▕ 
     71▕ test('broadcast view defaults to public channel when private is not set', function () {
     72▕     $rendered = view('sweetalert2::broadcast', ['channel' => 'general'])->render();

  1   tests/Feature/BroadcastTest.php:68


  Tests:    2 failed, 42 passed (105 assertions)
  Duration: 0.95s

…od appears in rendered output

Agent-Logs-Url: https://github.com/sweetalert2/sweetalert2-laravel/sessions/f85925ac-bc0c-43b7-9dd0-e35e2750ef39

Co-authored-by: limonte <6059356+limonte@users.noreply.github.com>

Copilot AI commented May 10, 2026

Copy link
Copy Markdown
Contributor Author

@copilot 2 tests are still failing:

...

Fixed in fa5e476. The blade template was using a JS ternary, so both window.Echo.private(...) and window.Echo.channel(...) were always present in the rendered HTML regardless of the $private flag. Replaced it with a PHP-level @if ($isPrivate) / @else / @endif so only the relevant method call appears in the output.

@limonte

limonte commented May 10, 2026

Copy link
Copy Markdown
Member

@SlothLady WDYT about this?

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds real-time SweetAlert2 notifications via Laravel’s broadcasting system, enabling backend-triggered popups/toasts to appear in the browser without a page reload (public and private channels) while matching the existing session/livewire/inertia rendering + callback handling approach.

Changes:

  • Introduces SweetAlert2BroadcastEvent (ShouldBroadcastNow) and a sweetalert2::broadcast Blade partial that subscribes via Laravel Echo and calls Swal.fire() on incoming events.
  • Extends Swal with broadcast*() and broadcastPrivate*() helper methods mirroring the existing icon/toast shortcut API.
  • Adds comprehensive tests for the event, Blade partial rendering, and Swal broadcasting helpers; documents setup/usage in the README and updates Composer suggestions.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/BroadcastTest.php Adds tests covering the broadcast event, listener view, and Swal::broadcast*() helper behavior.
src/Swal.php Adds public/private broadcasting helper methods for popups and toasts.
src/ServiceProvider.php Registers resources/views/shared under the sweetalert2 namespace to expose the broadcast partial.
src/Events/SweetAlert2BroadcastEvent.php New ShouldBroadcastNow event defining channel, event name, and payload.
resources/views/shared/broadcast.blade.php New Echo listener partial that loads SweetAlert2 (if needed) and safely parses callback options.
README.md Documents broadcasting setup and usage for public/private channels plus helper method lists.
composer.json Suggests laravel/reverb (or another broadcaster) for using the broadcasting feature.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread resources/views/shared/broadcast.blade.php Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Laravel broadcasting implementation

3 participants