You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -284,6 +285,141 @@ When a component can't be folded due to dynamic content, Blaze automatically fal
284
285
-**Test thoroughly**: After adding `@blaze`, verify the component still works correctly across different requests
285
286
-**Blaze is forgiving**: If a component can't be optimized, Blaze will automatically fall back to normal rendering
286
287
288
+
## Making impure components Blaze-eligible with @unblaze
289
+
290
+
Sometimes you have a component that's *mostly* static, but contains a small dynamic section that would normally prevent it from being folded (like `$errors`, `request()`, or `session()`). The `@unblaze` directive lets you "punch a hole" in an otherwise static component, keeping the static parts optimized while allowing specific sections to remain dynamic.
291
+
292
+
### The problem
293
+
294
+
Imagine a form input component that's perfect for `@blaze` - except it needs to show validation errors:
295
+
296
+
```blade
297
+
{{-- ❌ Can't use @blaze - $errors prevents optimization --}}
298
+
299
+
<div>
300
+
<label>{{ $label }}</label>
301
+
<input type="text" name="{{ $name }}">
302
+
303
+
@if($errors->has($name))
304
+
<span>{{ $errors->first($name) }}</span>
305
+
@endif
306
+
</div>
307
+
```
308
+
309
+
Without `@unblaze`, you have to choose: either skip `@blaze` entirely (losing all optimization), or remove the error handling (losing functionality).
310
+
311
+
### The solution: @unblaze
312
+
313
+
The `@unblaze` directive creates a dynamic section within a folded component:
314
+
315
+
```blade
316
+
{{-- ✅ Now we can use @blaze! --}}
317
+
318
+
@blaze
319
+
320
+
@props(['name', 'label'])
321
+
322
+
<div>
323
+
<label>{{ $label }}</label>
324
+
<input type="text" name="{{ $name }}">
325
+
326
+
@unblaze
327
+
@if($errors->has($name))
328
+
<span>{{ $errors->first($name) }}</span>
329
+
@endif
330
+
@endunblaze
331
+
</div>
332
+
```
333
+
334
+
**What happens:**
335
+
- The `<div>`, `<label>`, and `<input>` are folded (pre-rendered at compile time)
336
+
- The error handling inside `@unblaze` remains dynamic (evaluated at runtime)
337
+
- You get the best of both worlds: optimization + dynamic functionality
338
+
339
+
### Using scope to pass data into @unblaze
340
+
341
+
Sometimes you need to pass component props into the `@unblaze` block. Use the `scope` parameter:
<div>User #{{ $scope['userId'] }} - Last seen: {{ session('last_seen') }}</div>
355
+
@endif
356
+
@endunblaze
357
+
</div>
358
+
```
359
+
360
+
**How scope works:**
361
+
- Variables captured in `scope:` are encoded into the compiled view
362
+
- Inside the `@unblaze` block, access them via `$scope['key']`
363
+
- This allows the unblaze section to use component props while keeping the rest folded
364
+
365
+
### Nested components inside @unblaze
366
+
367
+
You can render other components inside `@unblaze` blocks, which is useful for extracting reusable dynamic sections:
368
+
369
+
```blade
370
+
@blaze
371
+
372
+
@props(['name', 'label'])
373
+
374
+
<div>
375
+
<label>{{ $label }}</label>
376
+
<input type="text" name="{{ $name }}">
377
+
378
+
@unblaze(scope: ['name' => $name])
379
+
<x-form.errors :name="$scope['name']" />
380
+
@endunblaze
381
+
</div>
382
+
```
383
+
384
+
```blade
385
+
{{-- components/form/errors.blade.php --}}
386
+
387
+
@props(['name'])
388
+
389
+
@error($name)
390
+
<p>{{ $message }}</p>
391
+
@enderror
392
+
```
393
+
394
+
This allows you to keep your error display logic in a separate component while still using it within the unblaze section. The form input remains folded, and only the error component is evaluated at runtime.
395
+
396
+
### Multiple @unblaze blocks
397
+
398
+
You can use multiple `@unblaze` blocks in a single component:
399
+
400
+
```blade
401
+
@blaze
402
+
403
+
<div>
404
+
<header>Static Header</header>
405
+
406
+
@unblaze
407
+
<div>Hello, {{ auth()->user()->name }}</div>
408
+
@endunblaze
409
+
410
+
<main>
411
+
{{-- Lots of static content --}}
412
+
</main>
413
+
414
+
@unblaze
415
+
<input type="hidden" value="{{ csrf_token() }}">
416
+
@endunblaze
417
+
418
+
<footer>Static Footer</footer>
419
+
</div>
420
+
```
421
+
422
+
Each `@unblaze` block creates an independent dynamic section, while everything else remains folded.
if (str_contains($template, '[STARTCOMPILEDUNBLAZE')) {
61
+
$template = preg_replace_callback('/(\[STARTCOMPILEDUNBLAZE:([0-9a-zA-Z]+)\])(.*?)(\[ENDCOMPILEDUNBLAZE\])/s', function ($matches) use (&$expressionsByToken) {
0 commit comments