Skip to content

Conversation

@ganyicz
Copy link
Collaborator

@ganyicz ganyicz commented Dec 26, 2025

The scenario

When using flux:avatar with Blaze, passing in dynamic variables, the component breaks.

@php
    $users = [
        'Filip Ganyicz',
        'Caleb Porzio',
        'Josh Hanley',
    ];
@endphp

<div class="mt-24 flex justify-center gap-2">
    @foreach($users as $name)
        <flux:avatar color="auto" :$name />
    @endforeach
</div>
SCR-20251226-mfpe

The problem

When Blaze renders the component, it replaces the dynamic variable with a placeholder:

<flux:avatar color="auto" name="ATTRIBUTE_PLACEHOLDER_0" />

This produces the output above, displaying At as the initials.

Normally, Blaze would restore placeholders found in the output to something like {{ $name }}.

But because the placeholder was cut off to the first two letters, Blaze won't find it.

The solution

I decided the best solution at this time is to remove @blaze completely until we have a better solution for a such a dynamic component as avatar is in Blaze.

I've attempted multiple solutions, both in Flux itself and by adding features to Blaze but none was ideal.

1. Using @unblaze

We could refactor and move the dynamic parts from @php blocks

@php
if ($name && ! $initials) {
    ...
}
@endphp

<span class="select-none">{{ $initials }}</span>

to be inside @unblaze:

@unblaze(scope: ['name' => $name])
<span class="select-none">{{ Flux::avatarInitials($name) }}</span>
@endunblaze

And this should work in theory, but it would require a significant refactoring and introduction of unprecedented patterns.

The biggest issue is the colors, which either need to remain in the blade file to be picked up by tailwind or to be whitelisted.

Flux::avatarColor($name ?? $colorSeed, match($badgeColor) {
    'red' => 'bg-red-500 dark:bg-red-400',
    'orange' => 'bg-orange-500 dark:bg-orange-400',
    'amber' => 'bg-amber-500 dark:bg-amber-400',
    // And 16 more...
})

These classes are then passed into the parent div attributes so this entire part would need to be in an @unblaze block above the markup:

@blaze

@props([])

@php
...
@endphp

@unblaze(scope: ['name' => $name ?? $slot, 'colorSeed' => $colorSeed])
$avatarColors = match(Flux::avatarColor($name, $colorSeed)) {
    ...
}
@endunblaze

<div {{ $attributes->class($classes)->merge(['class' => $avatarColors])>
...
</div>

I abandoned this solution as it was too complicated, messy and unprecedented.

2. Automatically abort folding

The core issue is that when Blaze doesn't find the cut-off placeholder, it will consider the fold as successful.

We could change this behavior and abort fold when a placholder is not found in the output.

Which is probably a good feature to have in Blaze and I can submit a PR for that.

But I found multiple ways this would break anyway:

a) If the user also passes src attribute, the name will appear in alt uncut, bypassing this check.
b) When folding is aborted, Blaze will resort to memoization, resulting in repeating initials.
c) If Blaze suceeds the fold and src is passed in, it will only render the <img> tag, completely dropping the initials which are often used as a fallback when image is not available

3. Manually abort folding

I added a new Blaze::abort() feature we could use when we detect that the component should use dynamic parts:

@php
if ($name && ! $initials) {
    Blaze::abort();
}
@endphp

This would stop Blaze from both folding and memoization and leave the component untouched.

Again, this might be a good feature to have in Blaze and I can submit a PR for it.

Although, it's still brittle as the php code containing the abort will never truly run in runtime.

@foreach($users as $user)
<flux:avatar :name="$user->name" :initials="$user->initials" :src="$user->avatar" />
@endforeach

In the above example the abort will never be hit because Blaze will replace all dynamic variables with string.

And again, we loose the fallback if $user->avatar or $user->initials is null.

Fixes #2108

@ganyicz ganyicz mentioned this pull request Dec 26, 2025
3 tasks
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.

Blaze breaks Avatar

2 participants