Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ux Live Component Laravel Package

symfony/ux-live-component

Build interactive UIs in Symfony with Live Components: stateful Twig components that update via Ajax without writing custom JavaScript. Handle actions, validation, and form binding, with predictable server-side rendering and smooth partial updates.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require symfony/ux-live-component
   npm install @symfony/stimulus-bridge @symfony/ux-live-component
   npm run build

Ensure StimulusBundle and UxLiveComponentBundle are enabled in config/bundles.php.

  1. Basic Component:

    // src/Components/MyComponent.php
    use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
    use Symfony\UX\LiveComponent\Attribute\LiveProp;
    
    #[AsLiveComponent]
    class MyComponent
    {
        #[LiveProp]
        public string $name = 'World';
    
        public function greet(): string
        {
            return "Hello, {$this->name}!";
        }
    }
    
  2. Template:

    {# templates/components/my_component.html.twig #}
    <h1>{{ greet() }}</h1>
    <input data-model="name">
    
  3. Register in Twig:

    {% import '@MyComponent' as MyComponent %}
    {{ MyComponent\MyComponent() }}
    
  4. Trigger Live Updates: Add the Stimulus controller to your layout (e.g., base.html.twig):

    {{ stimulus_controller('live-component') }}
    

First Use Case: Dynamic Form

Create a form where fields update without full page reloads:

#[AsLiveComponent]
class UserFormComponent
{
    #[LiveProp]
    public User $user;

    public function save(): void
    {
        // Save logic (e.g., $this->user->save())
        $this->dispatchBrowserEvent('user-saved');
    }
}
{# templates/components/user_form.html.twig #}
<form data-action="submit->live#submit">
    <input data-model="user.firstName">
    <input data-model="user.lastName">
    <button type="submit">Save</button>
</form>

Implementation Patterns

Core Workflows

1. Data Binding with LiveProp

  • Scalar Values:

    #[LiveProp(writable: ['email'])]
    public string $email;
    
    <input data-model="email">
    
  • Objects/Entities:

    #[LiveProp(writable: ['user'])]
    public User $user;
    
    <input data-model="user.firstName">
    
  • Arrays:

    #[LiveProp(writable: ['tags'])]
    public array $tags = [];
    
    <input data-model="tags.0">
    
  • Custom Hydration:

    #[LiveProp(useSerializerForHydration: true)]
    public array $complexData;
    

2. Actions and Events

  • Trigger Actions:

    <button data-action="click->live#update--action(save)">Save</button>
    
    public function save(): void
    {
        // Logic
        $this->dispatchBrowserEvent('user-saved');
    }
    
  • Browser Events:

    public function __construct()
    {
        $this->dispatchBrowserEvent('custom-event', ['data' => 'value']);
    }
    

3. Child Components

  • Parent-Child Communication:
    #[AsLiveComponent]
    class ParentComponent {
        #[LiveProp]
        public string $message;
    
        public function notifyChild(): void
        {
            $this->dispatchBrowserEvent('child-update', ['message' => $this->message]);
        }
    }
    
    {{ childComponent({ message: message }) }}
    
    // In child component's Stimulus controller
    this.component.on('child-update', (event) => {
        this.message = event.detail.message;
    });
    

4. Forms with Validation

  • Using ValidatableComponentTrait:
    use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
    use Symfony\UX\LiveComponent\ValidatableComponentTrait;
    
    #[AsLiveComponent]
    class UserFormComponent
    {
        use ValidatableComponentTrait;
    
        #[LiveProp]
        public User $user;
    
        public function submit(): void
        {
            if ($this->validate()) {
                $this->user->save();
            }
        }
    }
    
    <form data-action="submit->live#submit">
        <input data-model="user.email" data-error="errors.email">
        {{ errors|render }}
    </form>
    

5. Dynamic Templates

  • Method-Based Templates:
    #[AsLiveComponent(template: FromMethod('getTemplate'))]
    class DynamicComponent {
        public function getTemplate(): string
        {
            return $this->isAdmin() ? 'admin_template' : 'user_template';
        }
    }
    

Integration Tips

1. With Symfony Forms

  • Embedded Forms:
    #[LiveProp]
    public UserType $form;
    
    public function __construct()
    {
        $this->form = $this->createForm(UserType::class);
    }
    
    {{ form_start(form) }}
        {{ form_widget(form) }}
    {{ form_end(form) }}
    

2. With Doctrine

  • Entity Hydration:
    #[LiveProp(writable: ['user'])]
    public User $user;
    
    public function save(): void
    {
        $entityManager = $this->getEntityManager();
        $entityManager->persist($this->user);
        $entityManager->flush();
    }
    

3. With Stimulus

  • Custom JavaScript:
    // assets/controllers/my_component_controller.js
    import { Controller } from '@hotwired/stimulus';
    
    export default class extends Controller {
        connect() {
            this.component.on('user-saved', () => {
                alert('User saved!');
            });
        }
    }
    
    {{ stimulus_controller('my-component', { target: '#my-component' }) }}
    

4. Asset Mapping

  • Dynamic Assets:
    #[AsLiveComponent]
    class AssetComponent {
        #[LiveProp]
        public string $assetPath;
    
        public function getAssetUrl(): string
        {
            return $this->assetMapper->getUrl($this->assetPath);
        }
    }
    

5. Testing

  • PHPUnit Tests:
    use Symfony\UX\LiveComponent\Test\InteractsWithLiveComponents;
    
    class MyComponentTest extends TestCase {
        use InteractsWithLiveComponents;
    
        public function testComponent()
        {
            $component = $this->createLiveComponent(MyComponent::class);
            $rendered = $component->render();
    
            $this->assertSelectorTextContains('h1', 'Hello, World!');
            $this->assertComponentDispatchBrowserEvent($rendered, 'user-saved');
        }
    }
    

Gotchas and Tips

Pitfalls

1. CSRF and Security

  • Always Require X-Requested-With: Ensure your CORS configuration includes X-Requested-With:
    # config/packages/nextras_cors.yaml
    nextras_cors:
        paths:
            '^/api/*':
                allow_origin: ['*']
                allow_methods: ['GET', 'POST', 'PUT', 'DELETE']
                allow_headers: ['Content-Type', 'X-Requested-With']
                expose_headers: ['X-Requested-With']
    
  • Checksum Mismatches: Upgrading Live Component may break existing sessions due to checksum changes. Notify users to reload the page.

2. Data Binding Quirks

  • Boolean Checkboxes: Omit the value attribute for boolean binding:
    <input type="checkbox" data-model="isActive">
    
  • Arrays and Objects: Ensure proper serialization for complex types:
    #[LiveProp(useSerializerForHydration: true)]
    public array $nestedData;
    

3. Performance

  • Avoid Unnecessary Re-renders: Use #[LiveProp(writable: false)] for read-only props.
    #[LiveProp(writable: false)]
    public string $readonlyValue;
    
  • Batch Requests: Live Component batches updates by default. For immediate feedback, use:
    <button data-action="click->live#update--action(save)|norender">Save (no re-render)</button>
    

4. Child Components

  • Update Propagation: Child components do not auto-update unless explicitly allowed:
    #[LiveProp(acceptUpdatesFromParent: true)]
    public string $parentData;
    
  • Circular Dependencies: Avoid deep nesting of components to prevent performance issues.

5. Template Resolution

  • Dynamic Templates: Ensure your `FromMethod
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
andydefer/laravel-cluster
aimeos/ai-admin-mcp
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor