From 5acf4d9af2f33c163373057b60f1bda642413d67 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 2 Jun 2026 17:00:55 +0200 Subject: [PATCH] fix(navigation): strip stale x-cloak after Livewire navigation Remove leftover x-cloak attributes after wire:navigate events so morphed pages do not stay hidden, while keeping the initial-load cloak guard covered by a feature test. --- resources/js/app.js | 8 ++++++++ tests/Feature/NavigationCloakTest.php | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 tests/Feature/NavigationCloakTest.php diff --git a/resources/js/app.js b/resources/js/app.js index 4dcae5f8e..96085bd96 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -1,5 +1,13 @@ import { initializeTerminalComponent } from './terminal.js'; +// Livewire 3.5.19+ re-applies `x-cloak` to morphed elements during wire:navigate +// (via replaceHtmlAttributes). With `[x-cloak]{display:none}` on the app wrapper, +// this blanks the whole page on every navigation until Alpine re-processes it. +// Strip leftover x-cloak after each navigation; the initial-load FOUC guard stays. +document.addEventListener('livewire:navigated', () => { + document.querySelectorAll('[x-cloak]').forEach((el) => el.removeAttribute('x-cloak')); +}); + ['livewire:navigated', 'alpine:init'].forEach((event) => { document.addEventListener(event, () => { // tree-shaking diff --git a/tests/Feature/NavigationCloakTest.php b/tests/Feature/NavigationCloakTest.php new file mode 100644 index 000000000..430400ea7 --- /dev/null +++ b/tests/Feature/NavigationCloakTest.php @@ -0,0 +1,16 @@ +toContain("document.addEventListener('livewire:navigated'") + ->toContain("querySelectorAll('[x-cloak]')") + ->toContain("removeAttribute('x-cloak')"); +}); + +it('keeps the initial-load x-cloak guard on the app wrapper', function () { + $layout = file_get_contents(resource_path('views/layouts/app.blade.php')); + + expect($layout)->toContain('x-cloak'); +});