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'); +});