0

I am using Laravel v12 with Filament v4 and TailwindCSS v4.

I wanted to build a site with tabs, witch are a Livewire component inside filament/Page. In this Livewire components I have 3 tabs, where each has a Livewire component inside a @foreach loop:

<div wire:key="subscriptions-widget" class="flex flex-col">
    <div>
        <div class="">
            <div class="border-b border-gray-200 dark:border-white/10">
                <nav aria-label="Tabs" class="-mb-px flex space-x-4">
                    @foreach($availableTabs as $tabKey => $tab)
                        <a wire:key="subTab-{{$tabKey}}" @click="$wire.changeTab('{{$tabKey}}')"
                            @class([
                                $communesTabClasses,
                                $selectedTabClasses => $tabOption === $tabKey,
                                $inactiveTabClasses => $tabOption != $tabKey,
                        ])>
                            <svg viewBox="0 0 20 20" fill="currentColor" data-slot="icon" aria-hidden="true"
                                 @class([
                                    'mr-2 -ml-0.5 size-5 hidden sm:block',
                                    'text-indigo-500 dark:text-indigo-400' => $tabOption === $tabKey,
                                    'text-gray-400 group-hover:text-gray-500 dark:text-gray-500 dark:group-hover:text-gray-400' => $tabOption != $tabKey,
                                ])
                            >
                                <path d="M10 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM3.465 14.493a1.23 1.23 0 0 0 .41 1.412A9.957 9.957 0 0 0 10 18c2.31 0 4.438-.784 6.131-2.1.43-.333.604-.903.408-1.41a7.002 7.002 0 0 0-13.074.003Z" />
                            </svg>
                            <span class="">{{$tab['label']}}</span>
                        </a>
                    @endforeach
                </nav>
            </div>
        </div>
    </div>

    <div class="min-h-[300px] flex items-center">
        @if($tabOption === 'activeSubs')
            @if($subscriptions->count() >= 1)
                <div class="flex gap-4">
                    @foreach($subscriptions as $subscription)
                        <div wire:key="subs-card-{{$subscription->id}}">
                            <livewire:subscription-card
                                :subscription=$subscription
                                :isSubs=true
                            />
                        </div>
                    @endforeach
                </div>
            @else
                <div class="flex flex-col border-gray-500 border-1 max-w-[500px] mx-auto py-2 px-3 ">
                    <h1 class="text-center font-bold">Brak aktywnych subskrypcji</h1>
                    <span class="text-gray-800 ">W przypadku problemów, pomoc uzyskasz za pomocą kontaktu z nami!</span>
                </div>
            @endif
        @elseif($tabOption === 'expiredSubs')
            <livewire:company-expired-subscriptions-component />
        @elseif($tabOption === 'upgradeCompany')
            <livewire:company-subscriptions-recommend-component />
        @endif
    </div>
    <div>
        @livewire('company-subscriptions-feature-component')
    </div>
</div>

Ignore code quality, cause this is not last version of this page.

Problem is here:

<div class="min-h-[300px] flex items-center">
    @if($tabOption === 'activeSubs')
        @if($subscriptions->count() >= 1)
            <div class="flex gap-4">
                @foreach($subscriptions as $subscription)
                    <div wire:key="subs-card-{{$subscription->id}}">
                        <livewire:subscription-card
                            :subscription=$subscription
                            :isSubs=true
                        />
                    </div>
                @endforeach
            </div>
        @else
            <div class="flex flex-col border-gray-500 border-1 max-w-[500px] mx-auto py-2 px-3 ">
                <h1 class="text-center font-bold">Brak aktywnych subskrypcji</h1>
                <span class="text-gray-800 ">W przypadku problemów, pomoc uzyskasz za pomocą kontaktu z nami!</span>
            </div>
        @endif
    @elseif($tabOption === 'expiredSubs')
        <livewire:company-expired-subscriptions-component />
    @elseif($tabOption === 'upgradeCompany')
        <livewire:company-subscriptions-recommend-component />
    @endif
</div>

Inside a <livewire:company-expired-subscriptions-component /> is another blade file, witch has a problem that I mentioned.

@if($missingSubscriptions->count() >= 1)
<div class="flex gap-4 mt-4 w-full">
    @foreach($missingSubscriptions as $subscription)
        <div class="contents" >
            <livewire:subscription-card
                :subscription="$subscription"
                :isSubs=false
                wire:key="subs-card--{{$subscription->id}}"
            />
        </div>
    @endforeach
</div>
@else
<div class="flex flex-col border-gray-500 border-1 max-w-[500px] mx-auto py-2 px-3 ">
    <h1 class="text-center font-bold"></h1>
    <span class="text-gray-800 "></span>
</div>
@endif

If $missingSubscriptions are 2 or greater program works like expected, but if $missingSubscriptions is equal "1" site throwing error:

livewire.js?id=df3a17f2:4661 Uncaught Component not found: adsdzg1lAHJIVEntIZn3

Additionally, this code above generate this in DOM:

Good Wrong
Additionally, this code above generate this in DOM: Where working code with an enter between @foreach and div generates this:
Good generate wrong generate

A main difference is that (bug) generates a <div> with a children, when "good code" doesn't. To make it work I had to add a new line after @foreach(xx as xx), or delete a div element and let <livewire:xx> alone.

Can someone explain me why this happens or it is a bug?

PS: I have tried to set a wire:key on different elements, but this changing nothing, only an enter and alone livewire() work.

2
  • 1
    The generated HTML doesn't seem to match the code, e.g. <div class="contents" > is missing. And I suggest you view the page source, the inspector will automatically fix tag errors. Commented Nov 22 at 8:09
  • @shingo If I understand it well, contents is a special Tailwind class, that makes div invisible. All atributes should be copied to his childs, and this div should dissapear. I can be wrong, cause chatgpt said this. It is not a good source of knowledge, but somethimes helps.. Even not, changing this class doesn't repairs this bug. I have to delete this div. Commented Nov 24 at 7:56

1 Answer 1

1

Nested components rendered inside a loop require the :key attribute, whereas you're using the wire:key attribute, which is used for regular HTML tags (not components).

In short, the subscription-card component must be referenced like this:

<livewire:subscription-card
    :subscription="$subscription"
    :isSubs=false
    :key="'subs-card--' . $subscription->id"
/>

Here, you can find the related documentation (see the second case)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.