How to dynamically change a Livewire Component contents with blade templates properly?

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

How to Dynamically Change a Livewire Component Contents with Blade Templates Properly

Building dynamic user interfaces with Livewire is one of its greatest strengths. The ability to react to user input and instantly update the view without writing extensive vanilla JavaScript is incredibly powerful. However, when you introduce complexity—like conditionally loading large sets of form fields based on user selection—you inevitably run into edge cases related to state management and the component's rendering lifecycle.

The issue you are facing with dynamic @include directives and subsequent form submissions returning null keys is a classic symptom of a mismatch between the data being sent from the view and the properties expected by the Livewire component controller during its update cycle. As a senior developer, I can tell you that while Blade includes work for static content, relying on them to dictate dynamic state changes in Livewire often introduces brittle behavior.

Let’s break down why this happens and how to implement a robust solution.

Understanding the State Mismatch Problem

Your observation points to a fundamental flaw in how the component is reconstructing its state upon interaction:

  1. View Rendering: When you use @if/@include, the view renders a specific set of HTML based on session('typeBien').
  2. Form Submission: When a form updates, the data sent back to the component controller must map directly to the properties defined in the component class.
  3. The Conflict: If the structure (the included templates) changes dynamically, and you rely solely on standard form bindings without explicitly re-evaluating the entire necessary state within the Livewire component's methods, the framework struggles to reconcile the old state with the new rendered structure, leading to null keys or crashes during validation (like when calling Str::studly).

The attempts you made—using $this->reset() or removing @include directives—failed because they addressed symptoms rather than the root cause of the dynamic data flow. Simply resetting fields clears the input but doesn't force Livewire to re-evaluate which structure should be present.

The Recommended Approach: Data-Driven Rendering over Conditional Includes

Instead of using conditional Blade includes (@include) to define the entire component structure, the most robust pattern in Livewire is to manage the data that controls the view, and let Livewire handle the rendering based on that data. This keeps your component logic centralized and ensures state synchronization is always explicit.

Step 1: Centralize Data Management

Instead of relying on session checks inside the view, pass the required context data directly into the component as public properties or use a single data structure to determine which fields should be visible.

In your Livewire component class (e.g., app/Http/Livewire/Inscription.php):

namespace App\Http\Livewire;

use Livewire\Component;

class Inscription extends Component
{
    public $typeBien = 'maison'; // Initialize the type
    public $formData = [];      // Container for all form data

    public function render()
    {
        // Determine which fields to display based on the current state
        $fieldsToLoad = match ($this->typeBien) {
            'maison' => ['house_field', 'address_field'],
            'appartement' => ['flat_field', 'city_field'],
            'terrain' => ['plot_size_field', 'location_field'],
            default => [],
        };

        return view('livewire.inscription', [
            'currentType' => $this->typeBien,
            'fieldsToLoad' => $fieldsToLoad,
            'formData' => $this->formData,
        ]);
    }
}

Step 2: Dynamic Blade Rendering

Now, your Blade view simply iterates over the data passed from the component to dynamically render only the necessary fields. This completely bypasses the complex and error-prone dynamic @include logic for form structure.

In livewire/inscription.blade.php:

<div>
    <h2>Property Details</h2>

    {{-- Dynamically render fields based on the data passed from the component --}}
    @foreach ($fieldsToLoad as $fieldName)
        <div class="form-group">
            <label for="{{ $fieldName }}">Field Name</label>
            <input type="text" id="{{ $fieldName }}" wire:model.live="{{ $fieldName }}">
        </div>
    @endforeach

    {{-- Example of a static field that always appears --}}
    <div class="form-group">
        <label for="type_bien">Property Type</label>
        <select id="type_bien" wire:model="typeBien">
            <option value="maison">Maison</option>
            <option value="appartement">Appartement</option>
            {{-- ... other options --}}
        </select>
    </div>

    <button wire:click="submitData">Submit</button>
</div>

Step 3: Handling Submissions

When the user submits, the form data is naturally bound to the component's public properties ($formData and $typeBien). When you call wire:submit.prevent, Livewire automatically packages all current state values into an array that is sent to the server. Since the structure of the view is defined by the PHP logic, any submitted data will correctly map to the corresponding keys in your controller method, eliminating the null key errors entirely.

By adopting this data-driven rendering approach, you move the complexity from brittle Blade directives into manageable, testable PHP logic, which aligns perfectly with best practices for building scalable applications on Laravel and Livewire. Remember, good state management is the foundation of any successful application, whether you are working with Eloquent models or complex frontend interactions, just as you would in a robust framework like those provided by laravelcompany.com.

Conclusion

Dynamically changing component content using conditional Blade includes often leads to synchronization errors because it separates the visual structure from the underlying data state too much. The solution is to treat your view as purely a presentation layer driven entirely by the component's public properties. By calculating which fields are needed in the PHP class and iterating over those results in the Blade file, you ensure that the data sent during form submission is always complete and correctly keyed. This pattern provides stability, predictability, and greatly reduces debugging time.