a web application written in JavaScript ➔ The application fetches data to display from a web API (the Symfony/API Platform app) ➔ On user interaction (click, form submission…), the JavaScript app sends a request to the server and updates the DOM using the content of the response
losing the benefits of modern applications ➔ Relies on a client-side, HTML-driven micro-framework (Hotwired, written in JS)... ➔ but mostly on the features built into the web platform (web components, importmap…) ➔ In most cases, you don’t have to write JS by yourself, just use Symfony and Twig, as usual Benefits: ➔ Easier to write (Symfony/Twig + HTML) ➔ More reliable (simple) ➔ Better time to market ➔ Easier recruiting ➔ Happier devs (1 programming language)
➔ Traditional e-commerce websites ➔ Small/simple business apps You get for free: ➔ Incredible cache dynamics (when used with Varnish, Cloudflare, Fastly…) ➔ Good SEO (fast 1st page load)
native applications that can operate offline ➔ Advanced, non-HTML user interfaces: video games, 3D, Virtual Reality, advanced editors à la Google Docs… ➔ Heavy usage of device hardware: GPS, Bluetooth, gyroscope, camera… ➔ IoT
API: REST / RDF / GraphQL ➔ Built for containers / Kubernetes ➔ First class integration with popular “heavy” frontend technologies: ◆ React/Next.js ◆ Vue.js/Nuxt ◆ React Native/Expo
SPA! ➔ Watches for clicks and form submissions ➔ Loads pages in the background using fetch() ➔ Replaces the <body>, merges the <head> ➔ Changes browser’s history using history.pushState ➔ Customizable progress bar
➔ Update parts of the page (blocks) ➔ Capture links and forms in this frame ➔ The content of the frame is extracted from the response, and the existing content is replaced ➔ The response can contain the full page, or only a fragment ➔ A page can contain multiple frames
it in assets/controllers.json Turbo Streams ➔ Add real-time capabilities to your websites thanks to Mercure: server pushes changes to all connected users ➔ Stream page changes as fragments of HTML ➔ No JavaScript to write: only markup
Symfony\UX\Turbo\Attribute\Broadcast; #[ORM\Entity] #[Broadcast] // 🔥 The magic happens here class Book { #[ORM\Column, ORM\Id, ORM\GeneratedValue(strategy: "AUTO")] public ?int $id = null; #[ORM\Column] public string $title = ''; }
◆ Nuxt (Vue.js) ◆ Expo (React Native) ➔ Generate the code by reading the API documentation ◆ Supports Hydra and OpenAPI (experimental) ➔ Write you own templates ➔ Native support for Mercure (realtime updates) ➔ Work with existing Symfony apps: standalone packages available Scaffold your JavaScript apps
➔ No code by default (go to /admin) ◆ Read the API docs (Hydra or OpenAPI) ➔ Entirely customizable ➔ Built on top of React Admin, React, and MUI ➔ Automatic real time update through Mercure
Simple and easy, low JavaScript, just Symfony, Twig and HTML ➔ Fast as hell ➔ Best for CMS, e-commerce, small businesses apps API Platform (API + SPA): ➔ Unlock the full power of the web platform ➔ Still easy to use ➔ Best for complex apps, API-first, microservices, IoT