# Symfony Live Components dan UX 3.0: Aplikasi Reaktif Tanpa JavaScript di 2026 > Symfony Live Components memungkinkan pengembangan antarmuka reaktif dengan PHP dan Twig tanpa JavaScript. Tutorial lengkap LiveProp, LiveAction, form, dan deferred loading. - Published: 2026-05-10 - Updated: 2026-05-10 - Author: SharpSkill - Tags: symfony, live-components, ux-3, php, reactive - Reading time: 8 min --- Symfony Live Components menghadirkan antarmuka pengguna yang reaktif dan real-time sepenuhnya dalam PHP dan Twig. Dirilis pada April 2026, [Symfony UX 3.0](https://symfony.com/blog/symfony-ux-3-0-0-released) menghapus semua deprecation dari versi 2.x, menaikkan kebutuhan minimum ke PHP 8.4 dan Symfony 7.4, serta membuang empat paket usang — menghasilkan toolkit UX paling ramping hingga saat ini. > **Apa Itu Live Components?** > > Live Components mengubah setiap komponen Twig menjadi elemen stateful dan interaktif yang di-render ulang di sisi server saat pengguna berinteraksi — tanpa menulis JavaScript. Data binding, aksi, validasi, dan penanganan form semuanya terjadi di PHP. ## Menyiapkan Symfony UX 3.0 dengan Live Components Instalasi memerlukan Symfony 7.4+, PHP 8.4+, dan AssetMapper atau Webpack Encore untuk aset frontend. ```bash # terminal composer require symfony/ux-live-component # With AssetMapper (recommended for Symfony 7.4+) php bin/console importmap:require @symfony/ux-live-component # Verify installation php bin/console debug:twig --filter=component ``` AssetMapper menangani pengiriman JavaScript tanpa Node.js, Webpack, atau langkah build apapun. Stimulus controller yang mendukung Live Components dimuat secara otomatis. ## Membuat Komponen Pencarian Reaktif dengan LiveProp Sebuah search bar yang menyaring hasil saat pengguna mengetik — tanpa JavaScript sama sekali. Atribut `#[LiveProp]` menandai properti sebagai stateful, yang dipertahankan antar re-render melalui token terenkripsi yang aman untuk URL. ```php query) < 2) { return []; } return $this->productRepository->search( query: $this->query, category: $this->category === 'all' ? null : $this->category, limit: 20, ); } } ``` Template Twig yang bersesuaian mengikat input ke properti dengan `data-model`. ```twig {# templates/components/ProductSearch.html.twig #}
{% for product in this.products %}

{{ product.name }}

{{ product.price|format_currency('EUR') }}
{% else %} {% if query|length >= 2 %}

No results for "{{ query }}".

{% endif %} {% endfor %}
``` Modifier `debounce(300)` menunggu 300ms setelah ketikan terakhir sebelum mengirim request. Atribut `key` pada item daftar memungkinkan DOM morphing yang efisien — hanya elemen yang berubah yang diperbarui. > **URL Binding dengan LiveProp** > > Mengatur `url: true` pada LiveProp menyinkronkan nilai properti dengan URL browser sebagai query parameter. Hasil pencarian yang bisa di-bookmark dan dibagikan — dengan satu atribut saja. ## Menangani Aksi Pengguna dengan LiveAction Selain data binding, `#[LiveAction]` mengekspos metode PHP sebagai aksi yang dapat dipanggil dari frontend. Argumen dilewatkan melalui `#[LiveArg]`. ```php cartService->add($productId, $quantity); $this->items = $this->cartService->getItems(); // Notify other components on the page $this->emit('cart:updated', [ 'count' => count($this->items), ]); } #[LiveAction] public function removeItem(#[LiveArg] int $itemId): void { $this->cartService->remove($itemId); $this->items = $this->cartService->getItems(); $this->emit('cart:updated', ['count' => count($this->items)]); } public function getTotal(): float { return array_sum(array_map( fn(CartItem $item) => $item->getPrice() * $item->getQuantity(), $this->items, )); } } ``` Template memanggil aksi dengan helper `live_action()` atau atribut `data-action`. ```twig {# templates/components/ShoppingCart.html.twig #}

Cart ({{ items|length }})

{% for item in items %}
{{ item.name }} x{{ item.quantity }} {{ (item.price * item.quantity)|format_currency('EUR') }}
{% endfor %}
Total: {{ this.total|format_currency('EUR') }}
``` Metode `emit()` menyiarkan event ke Live Components lain pada halaman — misalnya komponen badge keranjang dapat mendengarkan dengan `#[LiveListener('cart:updated')]` dan memperbarui hitungannya tanpa reload halaman penuh. ## Validasi Form Real-Time Tanpa JavaScript Live Components terintegrasi langsung dengan [Symfony Forms](https://symfony.com/doc/current/forms.html). `ComponentWithFormTrait` menghubungkan state form, error validasi, dan submission ke lifecycle komponen. ```php createForm(RegistrationType::class, $this->initialFormData ?? new User()); } #[LiveAction] public function save(EntityManagerInterface $em): mixed { // Submits + validates — re-renders with errors if invalid $this->submitForm(); $user = $this->getForm()->getData(); $em->persist($user); $em->flush(); $this->addFlash('success', 'Account created.'); return $this->redirectToRoute('app_login'); } } ``` ```twig {# templates/components/RegistrationForm.html.twig #}
{{ form_start(form, { attr: { 'data-action': 'live#action:prevent', 'data-live-action-param': 'save' } }) }} {{ form_row(form.email) }} {{ form_row(form.plainPassword, { label: 'Password' }) }} {{ form_row(form.fullName) }} {{ form_end(form) }}
``` Error validasi muncul secara inline saat pengguna berpindah antar field — modifier `on(change)` pada `data-model` memicu re-render saat blur, menampilkan pesan constraint dari Symfony Validator secara instan. ## Deferred dan Lazy Loading untuk Performa Komponen berat — dashboard, grafik analitik, daftar panjang — mendapat manfaat dari deferred rendering. Alih-alih memblokir muat halaman awal, komponen menampilkan placeholder dan mengambil konten via AJAX setelah halaman siap. ```php analytics->getMetrics($this->period); } } ``` ```twig {# Parent page: load the dashboard after the page renders #} {# Or load when scrolled into view #} ``` Makro placeholder di dalam template komponen mendefinisikan apa yang dilihat pengguna saat konten asli dimuat. ```twig {# templates/components/AnalyticsDashboard.html.twig #}

Analytics — {{ period }}

{% for metric in this.metrics %}
{{ metric.label }} {{ metric.value|number_format }}
{% endfor %}
{% macro placeholder(props) %}
{% endmacro %} ``` Mode `loading="defer"` mengirim request AJAX segera saat halaman dimuat. Mode `loading="lazy"` menggunakan IntersectionObserver — request baru dikirim saat komponen masuk ke viewport. Kedua pendekatan menjaga respons halaman awal tetap cepat. > **CSRF Dihapus di UX 3.0** > > Symfony UX 3.0 mengganti token CSRF dengan perlindungan same-origin/CORS untuk Live Components. Argumen `csrf` pada `#[AsLiveComponent]` tidak lagi ada. Pastikan server menerapkan kebijakan same-origin. ## Komunikasi Antar Komponen dengan Events Live Components berkomunikasi melalui sistem event. Komponen child mengirim event; parent (atau sibling) mendengarkan dan bereaksi. ```php count = $cartService->getItemCount(); } // Automatically re-renders when ShoppingCart emits 'cart:updated' #[LiveListener('cart:updated')] public function onCartUpdated(#[LiveArg] int $count): void { $this->count = $count; } } ``` Pola ini menjaga komponen tetap terpisah. Komponen ShoppingCart tidak mereferensikan CartBadge secara langsung — event bus yang menangani koneksinya. ## Perubahan di Symfony UX 3.0 UX 3.0 adalah rilis pembersihan. Aplikasi yang berjalan tanpa peringatan deprecation pada 2.x dapat di-upgrade dengan gesekan minimal. | Perubahan | Sebelum (2.x) | Sesudah (3.0) | |-----------|---------------|---------------| | Perlindungan CSRF | `csrf: true` pada `#[AsLiveComponent]` | Same-origin/CORS (otomatis) | | Fungsi Twig CVA | `cva()` | `html_cva()` dari twig/html-extra 3.12+ | | Config defaults komponen | Opsional | `twig_component.defaults` wajib | | Paket dihapus | Swup, LazyImage, Typed, TogglePassword | Gunakan native API atau UX Toolkit | | Kebutuhan PHP | 8.1+ | 8.4+ | | Kebutuhan Symfony | 6.4+ | 7.4+ | [UX Toolkit](https://symfony.com/blog/symfonyux-2-32-0-released), yang diperkenalkan selama siklus 2.x, menyediakan komponen UI siap pakai (Button, Dialog, Card, Table, Pagination) yang di-style dengan Shadcn UI atau Flowbite 4.0 — menutup celah yang ditinggalkan oleh paket yang dihapus. Sedang mempersiapkan [pertanyaan wawancara Symfony](/technologies/symfony/interview-questions/events-subscribers)? Memahami Live Components dan sistem event semakin relevan untuk posisi senior. [Panduan pertanyaan wawancara Symfony](/blog/symfony/symfony-interview-questions) mencakup topik-topik dasar yang cocok dipadukan dengan pengetahuan praktis ini. ## Kesimpulan - Live Components menghilangkan kebutuhan akan framework JavaScript di sebagian besar aplikasi Symfony yang berat CRUD. Data binding, aksi, validasi, dan penanganan form tetap di PHP dan Twig - `#[LiveProp(writable: true, url: true)]` membuat antarmuka stateful yang bisa di-bookmark dan dibagikan dengan satu atribut - Deferred dan lazy loading (`loading="defer"` / `loading="lazy"`) menjaga muat halaman awal tetap cepat sementara komponen berat di-render secara asinkron - UX 3.0 menghapus token CSRF demi perlindungan same-origin/CORS — keamanan lebih sederhana dengan lebih sedikit bagian bergerak - Sistem event (`emit` / `#[LiveListener]`) memungkinkan komunikasi komponen yang terpisah tanpa manajemen state global - Untuk API, padukan Live Components dengan [API Platform pada Symfony 7](/blog/symfony/symfony-7-api-platform-best-practices) untuk arsitektur yang berat di backend --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/id/blog/symfony/symfony-live-components-ux-3-reactive-apps-without-javascript