From f5344217ab353e9479b654aa3d7bf26cf25ac687 Mon Sep 17 00:00:00 2001 From: Filip Ganyicz Date: Sat, 15 Aug 2026 16:05:08 +0200 Subject: [PATCH 01/11] Fix Livewire smart keys --- src/BladeRenderer.php | 11 +++++------ src/BladeService.php | 32 ++++++++++++++++++++++++++++++++ src/BlazeManager.php | 2 +- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/BladeRenderer.php b/src/BladeRenderer.php index 9a308736..9be20dd2 100644 --- a/src/BladeRenderer.php +++ b/src/BladeRenderer.php @@ -5,14 +5,12 @@ use Illuminate\Contracts\View\Factory; use Illuminate\Support\Arr; use Illuminate\Support\Facades\File; -use Illuminate\View\Compilers\BladeCompiler; use Illuminate\View\Component; use Illuminate\View\ComponentSlot; use Livewire\Blaze\Parser\Attribute; use Livewire\Blaze\Parser\Nodes\ComponentNode; use Livewire\Blaze\Parser\Nodes\SlotNode; use Livewire\Blaze\Runtime\BlazeRuntime; -use Livewire\Blaze\Support\ComponentSource; use Livewire\Blaze\Support\Utils; use ReflectionClass; @@ -22,7 +20,7 @@ class BladeRenderer { public function __construct( - protected BladeCompiler $blade, + protected BladeService $blade, protected Factory $factory, protected BlazeRuntime $runtime, protected BlazeManager $manager, @@ -64,17 +62,18 @@ public function render(ComponentNode $component, string $path): string 'translationReplacements' => [], ]); - $restoreCompiler = $this->freezeObjectProperties($this->blade, [ + $restoreCompiler = $this->freezeObjectProperties($this->blade->compiler, [ 'cachePath' => $temporaryCachePath, 'rawBlocks' => [], 'footer' => [], + 'precompilers' => $this->blade->precompilersForFolding(), 'prepareStringsForCompilationUsing' => [ function ($input) { if (Unblaze::hasUnblaze($input)) { $input = Unblaze::processUnblazeDirectives($input); }; - $input = $this->manager->compileForFolding($input, $this->blade->getPath()); + $input = $this->manager->compileForFolding($input, $this->blade->compiler->getPath()); return $input; }, @@ -102,7 +101,7 @@ function ($input) { try { if (! file_exists($compiled) || filemtime($path) > filemtime($compiled)) { - $this->blade->compile($path); + $this->blade->compiler->compile($path); } $awareData = Arr::mapWithKeys($component->parentsAttributes, function (Attribute $attribute) { diff --git a/src/BladeService.php b/src/BladeService.php index 31af937a..330d39ac 100644 --- a/src/BladeService.php +++ b/src/BladeService.php @@ -2,6 +2,8 @@ namespace Livewire\Blaze; +use Closure; +use Illuminate\Support\Arr; use Illuminate\Support\Facades\Event; use Illuminate\Support\Str; use Illuminate\View\Compilers\BladeCompiler; @@ -11,6 +13,7 @@ use Livewire\Blaze\Parser\Attribute; use Livewire\Blaze\Support\LaravelRegex; use ReflectionClass; +use ReflectionFunction; class BladeService { @@ -18,6 +21,8 @@ class BladeService protected ?array $customConditions = null; + protected ?array $precompilersForFolding = null; + public function __construct( public BladeCompiler $compiler, protected Factory $view, @@ -49,6 +54,33 @@ public function earliestPreCompilationHook(callable $callback): void }); } + /** + * Get the Blade precompilers that should run during isolated folding. + */ + public function precompilersForFolding(): array + { + return $this->precompilersForFolding ??= Arr::where( + (new ReflectionClass($this->compiler))->getProperty('precompilers')->getValue($this->compiler), + function ($precompiler) { + if ($precompiler instanceof \Livewire\Mechanisms\CompileLivewireTags\LivewireTagPrecompiler) { + return false; + } + + if (! $precompiler instanceof Closure) { + return true; + } + + $scope = (new ReflectionFunction($precompiler))->getClosureScopeClass()?->getName(); + + return ! in_array($scope, [ + \Livewire\Features\SupportCompiledWireKeys\SupportCompiledWireKeys::class, + \Livewire\Features\SupportMorphAwareBladeCompilation\SupportMorphAwareBladeCompilation::class, + \Livewire\Mechanisms\ExtendBlade\ExtendBlade::class, + ], true); + }, + ); + } + /** * Invoke the Blade compiler's storeUncompiledBlocks via reflection. */ diff --git a/src/BlazeManager.php b/src/BlazeManager.php index 2ed5db99..e959fb5f 100644 --- a/src/BlazeManager.php +++ b/src/BlazeManager.php @@ -49,7 +49,7 @@ public function __construct( protected BlazeRuntime $runtime, protected BladeService $blade, ) { - $this->renderer = new BladeRenderer($bladeCompiler, app('view'), $this->runtime, $this); + $this->renderer = new BladeRenderer($this->blade, app('view'), $this->runtime, $this); $this->parser = new Parser(new Tokenizer($this->blade), new AttributeParser($this->blade)); $this->walker = new Walker; $this->compiler = new Compiler($config, $this->blade, $this); From 62f67f4d5598db9b801ba782315861cc64e8b38c Mon Sep 17 00:00:00 2001 From: Filip Ganyicz Date: Sun, 23 Aug 2026 20:32:54 +0200 Subject: [PATCH 02/11] Exclude livewire only precompilers --- src/BladeService.php | 54 ++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/src/BladeService.php b/src/BladeService.php index 330d39ac..777b8b6c 100644 --- a/src/BladeService.php +++ b/src/BladeService.php @@ -12,9 +12,12 @@ use Livewire\Blaze\Compiler\DirectiveCompiler; use Livewire\Blaze\Parser\Attribute; use Livewire\Blaze\Support\LaravelRegex; +use Livewire\Mechanisms\ExtendBlade\ExtendBlade; use ReflectionClass; use ReflectionFunction; +use function Livewire\invade; + class BladeService { protected ComponentTagCompiler $tagCompiler; @@ -59,26 +62,37 @@ public function earliestPreCompilationHook(callable $callback): void */ public function precompilersForFolding(): array { - return $this->precompilersForFolding ??= Arr::where( - (new ReflectionClass($this->compiler))->getProperty('precompilers')->getValue($this->compiler), - function ($precompiler) { - if ($precompiler instanceof \Livewire\Mechanisms\CompileLivewireTags\LivewireTagPrecompiler) { - return false; - } - - if (! $precompiler instanceof Closure) { - return true; - } - - $scope = (new ReflectionFunction($precompiler))->getClosureScopeClass()?->getName(); - - return ! in_array($scope, [ - \Livewire\Features\SupportCompiledWireKeys\SupportCompiledWireKeys::class, - \Livewire\Features\SupportMorphAwareBladeCompilation\SupportMorphAwareBladeCompilation::class, - \Livewire\Mechanisms\ExtendBlade\ExtendBlade::class, - ], true); - }, - ); + if (isset($this->precompilersForFolding)) { + return $this->precompilersForFolding; + } + + $precompilers = (new ReflectionClass($this->compiler))->getProperty('precompilers')->getValue($this->compiler); + + if (! class_exists(\Livewire\Livewire::class)) { + return $this->precompilersForFolding = $precompilers; + } + + $livewireOnlyPrecompilers = invade(app(ExtendBlade::class))->precompilers; + + return $this->precompilersForFolding = Arr::where($precompilers, function ($precompiler) use ($livewireOnlyPrecompilers) { + if ($precompiler instanceof \Livewire\Mechanisms\CompileLivewireTags\LivewireTagPrecompiler) { + return false; + } + + if (in_array($precompiler, $livewireOnlyPrecompilers, true)) { + return false; + } + + if (! $precompiler instanceof Closure) { + return true; + } + + return ! in_array((new ReflectionFunction($precompiler))->getClosureScopeClass()?->getName(), [ + \Livewire\Features\SupportCompiledWireKeys\SupportCompiledWireKeys::class, + \Livewire\Features\SupportMorphAwareBladeCompilation\SupportMorphAwareBladeCompilation::class, + \Livewire\Mechanisms\ExtendBlade\ExtendBlade::class, + ], true); + }); } /** From b94cf550e7ecebef5182b2ab8ad13d187166b68b Mon Sep 17 00:00:00 2001 From: Filip Ganyicz Date: Sun, 23 Aug 2026 20:39:56 +0200 Subject: [PATCH 03/11] Move precompiler filtering to BladeRenderer --- src/BladeRenderer.php | 54 +++++++++++++++++++++++++++++++++++++------ src/BladeService.php | 46 ------------------------------------ src/BlazeManager.php | 2 +- 3 files changed, 48 insertions(+), 54 deletions(-) diff --git a/src/BladeRenderer.php b/src/BladeRenderer.php index 9be20dd2..133e2f88 100644 --- a/src/BladeRenderer.php +++ b/src/BladeRenderer.php @@ -2,9 +2,11 @@ namespace Livewire\Blaze; +use Closure; use Illuminate\Contracts\View\Factory; use Illuminate\Support\Arr; use Illuminate\Support\Facades\File; +use Illuminate\View\Compilers\BladeCompiler; use Illuminate\View\Component; use Illuminate\View\ComponentSlot; use Livewire\Blaze\Parser\Attribute; @@ -12,7 +14,11 @@ use Livewire\Blaze\Parser\Nodes\SlotNode; use Livewire\Blaze\Runtime\BlazeRuntime; use Livewire\Blaze\Support\Utils; +use Livewire\Mechanisms\ExtendBlade\ExtendBlade; use ReflectionClass; +use ReflectionFunction; + +use function Livewire\invade; /** * Handles isolated Blade rendering used during compile-time folding. @@ -20,7 +26,7 @@ class BladeRenderer { public function __construct( - protected BladeService $blade, + protected BladeCompiler $blade, protected Factory $factory, protected BlazeRuntime $runtime, protected BlazeManager $manager, @@ -62,18 +68,18 @@ public function render(ComponentNode $component, string $path): string 'translationReplacements' => [], ]); - $restoreCompiler = $this->freezeObjectProperties($this->blade->compiler, [ + $restoreCompiler = $this->freezeObjectProperties($this->blade, [ 'cachePath' => $temporaryCachePath, 'rawBlocks' => [], 'footer' => [], - 'precompilers' => $this->blade->precompilersForFolding(), + 'precompilers' => fn (array $precompilers) => $this->precompilersForFolding($precompilers), 'prepareStringsForCompilationUsing' => [ function ($input) { if (Unblaze::hasUnblaze($input)) { $input = Unblaze::processUnblazeDirectives($input); }; - $input = $this->manager->compileForFolding($input, $this->blade->compiler->getPath()); + $input = $this->manager->compileForFolding($input, $this->blade->getPath()); return $input; }, @@ -101,7 +107,7 @@ function ($input) { try { if (! file_exists($compiled) || filemtime($path) > filemtime($compiled)) { - $this->blade->compiler->compile($path); + $this->blade->compile($path); } $awareData = Arr::mapWithKeys($component->parentsAttributes, function (Attribute $attribute) { @@ -172,10 +178,12 @@ protected function freezeObjectProperties(object|string $object, array $properti $property = $reflection->getProperty($name); - $frozen[$name] = $property->getValue(is_object($object) ? $object : null); + $currentValue = $property->getValue(is_object($object) ? $object : null); + + $frozen[$name] = $currentValue; if (! is_numeric($key)) { - $property->setValue($object, $value); + $property->setValue($object, $value instanceof Closure ? $value($currentValue) : $value); } } @@ -186,4 +194,36 @@ protected function freezeObjectProperties(object|string $object, array $properti } }; } + + /** + * Get the Blade precompilers that should run during isolated folding. + */ + protected function precompilersForFolding(array $precompilers): array + { + if (! class_exists(\Livewire\Livewire::class)) { + return $precompilers; + } + + $livewireOnlyPrecompilers = invade(app(ExtendBlade::class))->precompilers; + + return Arr::where($precompilers, function ($precompiler) use ($livewireOnlyPrecompilers) { + if ($precompiler instanceof \Livewire\Mechanisms\CompileLivewireTags\LivewireTagPrecompiler) { + return false; + } + + if (in_array($precompiler, $livewireOnlyPrecompilers, true)) { + return false; + } + + if (! $precompiler instanceof Closure) { + return true; + } + + return ! in_array((new ReflectionFunction($precompiler))->getClosureScopeClass()?->getName(), [ + \Livewire\Features\SupportCompiledWireKeys\SupportCompiledWireKeys::class, + \Livewire\Features\SupportMorphAwareBladeCompilation\SupportMorphAwareBladeCompilation::class, + ExtendBlade::class, + ], true); + }); + } } diff --git a/src/BladeService.php b/src/BladeService.php index 777b8b6c..31af937a 100644 --- a/src/BladeService.php +++ b/src/BladeService.php @@ -2,8 +2,6 @@ namespace Livewire\Blaze; -use Closure; -use Illuminate\Support\Arr; use Illuminate\Support\Facades\Event; use Illuminate\Support\Str; use Illuminate\View\Compilers\BladeCompiler; @@ -12,11 +10,7 @@ use Livewire\Blaze\Compiler\DirectiveCompiler; use Livewire\Blaze\Parser\Attribute; use Livewire\Blaze\Support\LaravelRegex; -use Livewire\Mechanisms\ExtendBlade\ExtendBlade; use ReflectionClass; -use ReflectionFunction; - -use function Livewire\invade; class BladeService { @@ -24,8 +18,6 @@ class BladeService protected ?array $customConditions = null; - protected ?array $precompilersForFolding = null; - public function __construct( public BladeCompiler $compiler, protected Factory $view, @@ -57,44 +49,6 @@ public function earliestPreCompilationHook(callable $callback): void }); } - /** - * Get the Blade precompilers that should run during isolated folding. - */ - public function precompilersForFolding(): array - { - if (isset($this->precompilersForFolding)) { - return $this->precompilersForFolding; - } - - $precompilers = (new ReflectionClass($this->compiler))->getProperty('precompilers')->getValue($this->compiler); - - if (! class_exists(\Livewire\Livewire::class)) { - return $this->precompilersForFolding = $precompilers; - } - - $livewireOnlyPrecompilers = invade(app(ExtendBlade::class))->precompilers; - - return $this->precompilersForFolding = Arr::where($precompilers, function ($precompiler) use ($livewireOnlyPrecompilers) { - if ($precompiler instanceof \Livewire\Mechanisms\CompileLivewireTags\LivewireTagPrecompiler) { - return false; - } - - if (in_array($precompiler, $livewireOnlyPrecompilers, true)) { - return false; - } - - if (! $precompiler instanceof Closure) { - return true; - } - - return ! in_array((new ReflectionFunction($precompiler))->getClosureScopeClass()?->getName(), [ - \Livewire\Features\SupportCompiledWireKeys\SupportCompiledWireKeys::class, - \Livewire\Features\SupportMorphAwareBladeCompilation\SupportMorphAwareBladeCompilation::class, - \Livewire\Mechanisms\ExtendBlade\ExtendBlade::class, - ], true); - }); - } - /** * Invoke the Blade compiler's storeUncompiledBlocks via reflection. */ diff --git a/src/BlazeManager.php b/src/BlazeManager.php index e959fb5f..831daa3e 100644 --- a/src/BlazeManager.php +++ b/src/BlazeManager.php @@ -49,7 +49,7 @@ public function __construct( protected BlazeRuntime $runtime, protected BladeService $blade, ) { - $this->renderer = new BladeRenderer($this->blade, app('view'), $this->runtime, $this); + $this->renderer = new BladeRenderer($this->bladeCompiler, app('view'), $this->runtime, $this); $this->parser = new Parser(new Tokenizer($this->blade), new AttributeParser($this->blade)); $this->walker = new Walker; $this->compiler = new Compiler($config, $this->blade, $this); From bc9abb2e76054e2037f2890300e2660da54dca39 Mon Sep 17 00:00:00 2001 From: Filip Ganyicz Date: Sun, 23 Aug 2026 20:42:27 +0200 Subject: [PATCH 04/11] Formatting --- src/BladeRenderer.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/BladeRenderer.php b/src/BladeRenderer.php index 133e2f88..058e2f9d 100644 --- a/src/BladeRenderer.php +++ b/src/BladeRenderer.php @@ -7,14 +7,12 @@ use Illuminate\Support\Arr; use Illuminate\Support\Facades\File; use Illuminate\View\Compilers\BladeCompiler; -use Illuminate\View\Component; use Illuminate\View\ComponentSlot; use Livewire\Blaze\Parser\Attribute; use Livewire\Blaze\Parser\Nodes\ComponentNode; use Livewire\Blaze\Parser\Nodes\SlotNode; use Livewire\Blaze\Runtime\BlazeRuntime; use Livewire\Blaze\Support\Utils; -use Livewire\Mechanisms\ExtendBlade\ExtendBlade; use ReflectionClass; use ReflectionFunction; @@ -204,7 +202,7 @@ protected function precompilersForFolding(array $precompilers): array return $precompilers; } - $livewireOnlyPrecompilers = invade(app(ExtendBlade::class))->precompilers; + $livewireOnlyPrecompilers = invade(app(\Livewire\Mechanisms\ExtendBlade\ExtendBlade::class))->precompilers; return Arr::where($precompilers, function ($precompiler) use ($livewireOnlyPrecompilers) { if ($precompiler instanceof \Livewire\Mechanisms\CompileLivewireTags\LivewireTagPrecompiler) { @@ -222,7 +220,7 @@ protected function precompilersForFolding(array $precompilers): array return ! in_array((new ReflectionFunction($precompiler))->getClosureScopeClass()?->getName(), [ \Livewire\Features\SupportCompiledWireKeys\SupportCompiledWireKeys::class, \Livewire\Features\SupportMorphAwareBladeCompilation\SupportMorphAwareBladeCompilation::class, - ExtendBlade::class, + \Livewire\Mechanisms\ExtendBlade\ExtendBlade::class, ], true); }); } From b70c3947132e876eac7e41fd52efeb605af12c86 Mon Sep 17 00:00:00 2001 From: Filip Ganyicz Date: Sun, 23 Aug 2026 21:02:28 +0200 Subject: [PATCH 05/11] Formatting --- src/BladeRenderer.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/BladeRenderer.php b/src/BladeRenderer.php index 058e2f9d..c1d4508c 100644 --- a/src/BladeRenderer.php +++ b/src/BladeRenderer.php @@ -70,7 +70,7 @@ public function render(ComponentNode $component, string $path): string 'cachePath' => $temporaryCachePath, 'rawBlocks' => [], 'footer' => [], - 'precompilers' => fn (array $precompilers) => $this->precompilersForFolding($precompilers), + 'precompilers' => fn (array $precompilers) => $this->withoutLivewirePrecompilers($precompilers), 'prepareStringsForCompilationUsing' => [ function ($input) { if (Unblaze::hasUnblaze($input)) { @@ -194,9 +194,9 @@ protected function freezeObjectProperties(object|string $object, array $properti } /** - * Get the Blade precompilers that should run during isolated folding. + * Filter out Livewire-specific precompilers. */ - protected function precompilersForFolding(array $precompilers): array + protected function withoutLivewirePrecompilers(array $precompilers): array { if (! class_exists(\Livewire\Livewire::class)) { return $precompilers; From 767e34627183ac99d2baa671920945ee3453d8a4 Mon Sep 17 00:00:00 2001 From: Filip Ganyicz Date: Sun, 23 Aug 2026 21:08:07 +0200 Subject: [PATCH 06/11] Prevent folding of Livewire components --- src/Exceptions/InvalidBlazeFoldUsageException.php | 8 ++++++++ src/Folder/Folder.php | 2 ++ tests/Folder/FolderTest.php | 2 +- .../invalid-foldable/livewire-directive.blade.php | 3 +++ .../views/components/invalid-foldable/livewire.blade.php | 3 +++ 5 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/views/components/invalid-foldable/livewire-directive.blade.php create mode 100644 tests/fixtures/views/components/invalid-foldable/livewire.blade.php diff --git a/src/Exceptions/InvalidBlazeFoldUsageException.php b/src/Exceptions/InvalidBlazeFoldUsageException.php index e2aae66b..b71a9419 100644 --- a/src/Exceptions/InvalidBlazeFoldUsageException.php +++ b/src/Exceptions/InvalidBlazeFoldUsageException.php @@ -127,4 +127,12 @@ public static function forOnce(string $componentPath): self ); } + public static function forLivewire(string $componentPath): self + { + return new self( + $componentPath, + ' 'forAuth', 'request\\(\\)' => 'forRequest', 'old\\(' => 'forOld', + ' 'forLivewire', + '@livewire' => 'forLivewire', ]; foreach ($problematicPatterns as $pattern => $factoryMethod) { diff --git a/tests/Folder/FolderTest.php b/tests/Folder/FolderTest.php index c0a0889b..40a63e3b 100644 --- a/tests/Folder/FolderTest.php +++ b/tests/Folder/FolderTest.php @@ -301,7 +301,7 @@ expect(fn () => app(Folder::class)->fold($node)) ->toThrow(InvalidBlazeFoldUsageException::class); -})->with(['errors', 'session', 'error', 'csrf', 'auth', 'request', 'old', 'once']); +})->with(['errors', 'session', 'error', 'csrf', 'auth', 'request', 'old', 'once', 'livewire', 'livewire-directive']); test('does not fold components with slots wrapped in directives', function () { $input = '@if(false)Header@endif'; diff --git a/tests/fixtures/views/components/invalid-foldable/livewire-directive.blade.php b/tests/fixtures/views/components/invalid-foldable/livewire-directive.blade.php new file mode 100644 index 00000000..6b849516 --- /dev/null +++ b/tests/fixtures/views/components/invalid-foldable/livewire-directive.blade.php @@ -0,0 +1,3 @@ +@blaze(fold: true) + +@livewire('counter') diff --git a/tests/fixtures/views/components/invalid-foldable/livewire.blade.php b/tests/fixtures/views/components/invalid-foldable/livewire.blade.php new file mode 100644 index 00000000..072db7aa --- /dev/null +++ b/tests/fixtures/views/components/invalid-foldable/livewire.blade.php @@ -0,0 +1,3 @@ +@blaze(fold: true) + + From 463d2a092ba04742193cdf14c557abb09117016c Mon Sep 17 00:00:00 2001 From: Filip Ganyicz Date: Sun, 23 Aug 2026 22:50:03 +0200 Subject: [PATCH 07/11] Disable Livewire 2 precompiler --- src/BladeRenderer.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/BladeRenderer.php b/src/BladeRenderer.php index c1d4508c..45650ee7 100644 --- a/src/BladeRenderer.php +++ b/src/BladeRenderer.php @@ -221,6 +221,7 @@ protected function withoutLivewirePrecompilers(array $precompilers): array \Livewire\Features\SupportCompiledWireKeys\SupportCompiledWireKeys::class, \Livewire\Features\SupportMorphAwareBladeCompilation\SupportMorphAwareBladeCompilation::class, \Livewire\Mechanisms\ExtendBlade\ExtendBlade::class, + \Livewire\LivewireServiceProvider::class, ], true); }); } From 82c69292a543a0679236b2cbdf2912bf2a436806 Mon Sep 17 00:00:00 2001 From: Filip Ganyicz Date: Sun, 23 Aug 2026 22:56:48 +0200 Subject: [PATCH 08/11] Formatting --- src/BladeRenderer.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/BladeRenderer.php b/src/BladeRenderer.php index 45650ee7..cc1814c9 100644 --- a/src/BladeRenderer.php +++ b/src/BladeRenderer.php @@ -202,7 +202,9 @@ protected function withoutLivewirePrecompilers(array $precompilers): array return $precompilers; } - $livewireOnlyPrecompilers = invade(app(\Livewire\Mechanisms\ExtendBlade\ExtendBlade::class))->precompilers; + $livewireOnlyPrecompilers = class_exists(\Livewire\Mechanisms\ExtendBlade\ExtendBlade::class) + ? invade(app(\Livewire\Mechanisms\ExtendBlade\ExtendBlade::class))->precompilers + : []; return Arr::where($precompilers, function ($precompiler) use ($livewireOnlyPrecompilers) { if ($precompiler instanceof \Livewire\Mechanisms\CompileLivewireTags\LivewireTagPrecompiler) { @@ -213,16 +215,16 @@ protected function withoutLivewirePrecompilers(array $precompilers): array return false; } - if (! $precompiler instanceof Closure) { - return true; - } - - return ! in_array((new ReflectionFunction($precompiler))->getClosureScopeClass()?->getName(), [ + if ($precompiler instanceof Closure && in_array((new ReflectionFunction($precompiler))->getClosureScopeClass()?->getName(), [ \Livewire\Features\SupportCompiledWireKeys\SupportCompiledWireKeys::class, \Livewire\Features\SupportMorphAwareBladeCompilation\SupportMorphAwareBladeCompilation::class, \Livewire\Mechanisms\ExtendBlade\ExtendBlade::class, \Livewire\LivewireServiceProvider::class, - ], true); + ], true)) { + return false; + } + + return true; }); } } From a0ae6186b7f29b7fa962b32d95dc637fdf0e80df Mon Sep 17 00:00:00 2001 From: Filip Ganyicz Date: Sun, 23 Aug 2026 23:21:10 +0200 Subject: [PATCH 09/11] Abort fold for nested livewire components --- src/BladeRenderer.php | 12 +++++++++++- tests/Folder/FolderTest.php | 2 +- .../invalid-foldable/livewire-wrapped.blade.php | 3 +++ 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 tests/fixtures/views/components/invalid-foldable/livewire-wrapped.blade.php diff --git a/src/BladeRenderer.php b/src/BladeRenderer.php index cc1814c9..3e0aa8d1 100644 --- a/src/BladeRenderer.php +++ b/src/BladeRenderer.php @@ -8,6 +8,7 @@ use Illuminate\Support\Facades\File; use Illuminate\View\Compilers\BladeCompiler; use Illuminate\View\ComponentSlot; +use Livewire\Blaze\Exceptions\InvalidBlazeFoldUsageException; use Livewire\Blaze\Parser\Attribute; use Livewire\Blaze\Parser\Nodes\ComponentNode; use Livewire\Blaze\Parser\Nodes\SlotNode; @@ -70,7 +71,16 @@ public function render(ComponentNode $component, string $path): string 'cachePath' => $temporaryCachePath, 'rawBlocks' => [], 'footer' => [], - 'precompilers' => fn (array $precompilers) => $this->withoutLivewirePrecompilers($precompilers), + 'precompilers' => fn (array $precompilers) => [ + ...$this->withoutLivewirePrecompilers($precompilers), + function (string $input) use ($path) { + if (preg_match('~<\s*livewire[-:]|(? [ function ($input) { if (Unblaze::hasUnblaze($input)) { diff --git a/tests/Folder/FolderTest.php b/tests/Folder/FolderTest.php index 40a63e3b..8dfa1849 100644 --- a/tests/Folder/FolderTest.php +++ b/tests/Folder/FolderTest.php @@ -301,7 +301,7 @@ expect(fn () => app(Folder::class)->fold($node)) ->toThrow(InvalidBlazeFoldUsageException::class); -})->with(['errors', 'session', 'error', 'csrf', 'auth', 'request', 'old', 'once', 'livewire', 'livewire-directive']); +})->with(['errors', 'session', 'error', 'csrf', 'auth', 'request', 'old', 'once', 'livewire', 'livewire-directive', 'livewire-wrapped']); test('does not fold components with slots wrapped in directives', function () { $input = '@if(false)Header@endif'; diff --git a/tests/fixtures/views/components/invalid-foldable/livewire-wrapped.blade.php b/tests/fixtures/views/components/invalid-foldable/livewire-wrapped.blade.php new file mode 100644 index 00000000..0cf8c29f --- /dev/null +++ b/tests/fixtures/views/components/invalid-foldable/livewire-wrapped.blade.php @@ -0,0 +1,3 @@ +@blaze(fold: true) + + From 90ad35b8959d0b6684b745267cfb44b26a9f8d8c Mon Sep 17 00:00:00 2001 From: Filip Ganyicz Date: Sun, 23 Aug 2026 23:21:18 +0200 Subject: [PATCH 10/11] Formatting --- src/BladeRenderer.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/BladeRenderer.php b/src/BladeRenderer.php index 3e0aa8d1..8004b61a 100644 --- a/src/BladeRenderer.php +++ b/src/BladeRenderer.php @@ -71,16 +71,6 @@ public function render(ComponentNode $component, string $path): string 'cachePath' => $temporaryCachePath, 'rawBlocks' => [], 'footer' => [], - 'precompilers' => fn (array $precompilers) => [ - ...$this->withoutLivewirePrecompilers($precompilers), - function (string $input) use ($path) { - if (preg_match('~<\s*livewire[-:]|(? [ function ($input) { if (Unblaze::hasUnblaze($input)) { @@ -92,6 +82,16 @@ function ($input) { return $input; }, ], + 'precompilers' => fn (array $precompilers) => [ + ...$this->withoutLivewirePrecompilers($precompilers), + function (string $input) use ($path) { + if (preg_match('~<\s*livewire[-:]|(? null, 'forElseCounter' => 0, 'firstCaseInSwitch' => true, From d46ab6cd1bd69d7b4ff03559b1d28663eed8a950 Mon Sep 17 00:00:00 2001 From: Filip Ganyicz Date: Sun, 23 Aug 2026 23:23:57 +0200 Subject: [PATCH 11/11] Formatting --- src/BlazeManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BlazeManager.php b/src/BlazeManager.php index 831daa3e..2ed5db99 100644 --- a/src/BlazeManager.php +++ b/src/BlazeManager.php @@ -49,7 +49,7 @@ public function __construct( protected BlazeRuntime $runtime, protected BladeService $blade, ) { - $this->renderer = new BladeRenderer($this->bladeCompiler, app('view'), $this->runtime, $this); + $this->renderer = new BladeRenderer($bladeCompiler, app('view'), $this->runtime, $this); $this->parser = new Parser(new Tokenizer($this->blade), new AttributeParser($this->blade)); $this->walker = new Walker; $this->compiler = new Compiler($config, $this->blade, $this);