Need help with Drupal or Grav admin, site building, design, or content? Contact us!
Help Defend Democracy! → Join Battalion today.
Exploring the Symfony universe!
Let’s explore the magic that Stimulus JS brings to Symfony UX.
This is a companion article to Discover Symfony UX’s Twig Components. Read that first, as it contains more detailed Symfony UX information referenced here.
As mentioned in our Twig article, we are fans of componentization. It’s a philosophy similar to the S in SOLID programming principles. IYDK that’s the single responsibility principle.
And we are especially fans of the web components used in user interfaces. They are a fine example of componentization.
But we are not fans of JavaScript, especially for UI components. For a review of its clusterfuckiry see our article on Frontend Madness.
Thus, we love anything that simplifies using it or, better yet, eliminates JS. That’s why we use tools like CSSUI on this Drupal site. And never use JS when it’s not necessary. In other words, we use HTML and CSS as you should.
In a Symfony project’s UI, components are handled by a group of tools with the moniker of Symfony UX. This article is going to explore it and its non-Twig-related UI components.
If you have read our Twig Components article, you can skip to this.
If not, Symfony describes Symfony UX as “JavaScript tools you can't live without. They’re a set of PHP and JavaScript packages to solve everyday frontend problems featuring Stimulus and Turbo.”
“Symfony UX is an initiative and set of libraries to seamlessly integrate JavaScript tools into your application.
Behind the scenes, the UX packages leverage Stimulus: a small but powerful library for binding JavaScript functionality to elements on your page.”
Thank you, abstraction.
The short answer is when you install a package (aka Stimulus component), Symfony updates everything automagically.
The long answer, according to the docs is ⬇️.
“When you install a UX PHP package, Symfony Flex will automatically update your package.json
file to point to a "virtual package" that lives inside the PHP package.
The Flex recipe will also update your assets/controllers.json
file to add a new Stimulus controller to your app.
Finally, your assets/bootstrap.js
file - working with the @symfony/stimulus-bridge - package will automatically register:
assets/controllers/
as Stimulus controllers;assets/controllers.json
as Stimulus controllers.The end result: you install a package, and you instantly have a Stimulus controller available!”
FYI, the virtual package is the Stimulus JS node package.
Symfony UX / Stimulus controllers control your user interface. And thanks to them, you can do so without writing a ton of custom JavaScript. They handle the JS for you. You handle your PHP.
However, you can still write custom JavaScript inside Stimulus Controllers or use third-party components. If that floats your boat.
Why? Stimulus was created and is used by developers outside of Symfony (specifically Ruby on Rails). Thus additional tools are available beyond the Symfony UX packages.
In particular, according to their documentation:
You should always steal your rivals’ good ideas. And share yours. So props to Symfony.
As we just mentioned, you can use code from these third-party tools in your controllers.
Symfony docs say ⬇️:
“By default, all of your controllers (i.e. files in assets/controllers/
+ controllers in assets/controllers.json
) will be downloaded and loaded on every page.”
A quick note is warranted here. Symfony UX gives you powers. But with great power comes great responsibility. By the way, who said that? Uncle Ben? An Ancient Greek philosopher? 😉
So, just because you can use these doesn’t mean you should. Remember Jurassic Park. Plus, simpler is better and less is more.
As the image above indicates, there are twelve components to make your programming life easier.
You can explore them all here.
Or continue reading for the non-Twig-related ones 🌿.
We will look at and grade:
For non-American readers A = great, B = good, C = so-so, D = Crap, there is no E, F = Failure
We will publish an article in the future on Turbo🏃🏽. I’m thinking of “Discover Symfony UX: Turbo lets you say FU to SPAs” for the title.
Some of the components are useful. And IMHO some should be avoided whenever possible, like JS itself. When you should use HTML and CSS people, do so. And I don’t mean Failwind or Bootcrap. Use the languages directly and correctly.
Anyway, most of these components do implement JavaScript, while a few have a dash of Symfony and Ajax sprinkled in.
Autocomplete is an appropriate use of JS.
It provides smart form controls via Ajax-powered autocomplete and <select>.
The docs say:
“Breathe life into EntityType
and ChoiceType
fields with Tom Select and a sprinkle of Ajax.”
And Tom Select says:
“Tom Select is a dynamic, framework agnostic, and lightweight (~16kb gzipped) <select> UI control. With autocomplete and native-feeling keyboard navigation, it's useful for tagging, contact lists, country selectors, and so on. Tom Select was forked from selectize.js with four main objectives: modernizing the code base, decoupling from jQuery, expanding functionality, and addressing issue backlogs.”
Autocomplete gets an A+ grade.
Chart.JS is another appropriate use of JavaScript. Charts are useful for user experience and effective content.
The component lets you render graphs via chart.js.
Symfony says:
“Leverage the power of chart.js entirely from PHP.”
I say amen, brother.
And Chart.JS itself says it is “simple yet flexible JavaScript charting for designers and developers.”
And they are correct.
Chart.JS get an A+ too.
I would have chosen Vue, Alpine, or even Svelte for this component. But like WordPress, Symfony screwed up and chose React. Bigger is not better, and popular never is.
I stay away from it just like I stay away from religious fanatics, fascists, communists, conspiracy theorists, and stupid people in general.
There is too much JS in the world, to begin with, especially a clusterfuck like React. If I have to touch it, I hold my nose and use a 410-foot pole.
Plus, it’s from fucking Facebook.
But here’s the component link with more info if you’re interested.
Remember, if you are forced to use some SPA-like garbage UI by an evil boss or ignorant client, you can roll your own web components. Or use 3rd party components like Vue.
Fortunately, SymfonyCasts says you can use Vue in Stimulus controllers. Just not in the React component.
Better yet, use CSS components in your app or Stimulus components with Symfony UX.
Rant over and React gets a totally objective F. 😉
Update 9/8/2022.
Fortunately for you, Symfony UX just released a Vue component.
Vue explains the advantages of using it over something like React.
"The web is extremely diverse - the things we build on the web may vary drastically in form and scale. With that in mind, Vue is designed to be flexible and incrementally adoptable. Depending on your use case, Vue can be used in different ways:
Like Symfony with Vue you only use what you need. You progressively implement it.
The Symfony UX documentation says:
"Vue.js is a JavaScript framework for building user interfaces. Symfony UX Vue.js provides tools to render Vue components from Twig, handling rendering and data transfers.
Symfony UX Vue.js supports Vue.js v3 only.
UX Vue.js works by using a system of Vue.js controller components: Vue.js components that are registered using registerVueControllerComponents
and that are meant to be rendered from Twig."
And learn more about Vue 3 here.
Vue gets a totally objective A+. 😉
As the name implies, you can crop images with Image Cropper.
Symfony says:
“Let your users crop images with Cropper.js, then grab the final image from PHP. Simple.”
I say, why? 98.874% of the time, this is unnecessary for the frontend. Maybe if you are building a backend for someone? Or a photography tutorial app?
Image Cropper gets a B-.
Lazy loading images is an appropriate use of JS. So, hurray for Lazy Image.
Symfony says:
“Load fast with Lazy Images. Serve small or blurred images first, then load the real thing after the page loads.”
It’s an interesting implementation using BlurHash.
Blurhash says:
“BlurHash takes an image and gives you a short string (only 20-30 characters!) that represents the placeholder for this image. You do this on the backend of your service and store the string along with the image. When you send data to your client, you send both the URL to the image and the BlurHash string. Your client then takes the string and decodes it into an image that it shows while the real image is loading over the network. The string is short enough to comfortably fit into whatever data format you use. For instance, it can easily be added as a field in a JSON object.”
Lazy Image (if you need it) gets an A-.
This component lets you implement a styled upload zone in your app.
Symfony says:
“Native Upload Dropzone with style. Upgrade your upload field to a stylized "Dropzone" with file previews.”
The documentation says:
“The most common usage of Symfony UX Dropzone is to use it as a drop-in replacement of the native FileType class. It provides a default stylesheet to ease usage. You can disable it to add your design. Symfony UX Dropzone allows you to extend its default behavior using a custom Stimulus controller.”
This could be useful at times so Stylized Dropzone gets a B+.
Swup Integration can be used as an alternative to the Turbo component. That’s interesting.
You can create slick Ajax Page Transitions with Swup.
Symfony says:
“Replace full page refreshes with Ajax-powered, stylized page transitions.”
Swup.js says it’s a:
“Complete, flexible, extensible, and easy to use page transition library for your web.”
Swup Integration gets an A.
Notify provides native browser notifications.
Simple enough.
Symfony says:
“Notify users from inside PHP. Send real-time, native browser notifications to everyone via Symfony's Notifier Component.”
Their docs say:
“To use Symfony UX Notify you must have a running Mercure server and a properly configured notifier transport. Then, you can inject the NotifierInterface
service and send messages on the chat/myMercureChatter
channel. Finally, to "listen" and trigger the notifications in the user's browser, call the stream_notifications()
Twig function anywhere on the page.”
This is useful so Notify gets an A+.
Again, why? Maybe in a tutorial?
This is the type of half-assed and unnecessary JS functionality that plagues web design. You can see how annoying it is on the Symfony UX homepage.
But it’s a half-free world, so knock yourself out if interested.
Typed gets an objective C. 😉
Ok. School’s out.
Let’s hope there are more components on the way from Symfony UX. Alternatives to React insertion should top the list. Update 9/8/20022. They added a Vue component. Yay!
Carousel? No. Lightbox? Maybe. Dropdown? Yes. Textarea autogrow? 🤯
And if you have a request, let please Symfony know. You might want to make a donation as well. Let me rephrase that. Give them some money. Free riders suck.
You can use their commercial products like Symfony Insight, attend official Symfony conferences, buy the Symfony book, or if you are rich or own a company, sponsor them.
Money rant over, you now know more about Symfony UX and specifically its JS-related components. Which are most of them. The initiative and set of libraries seamlessly integrate JavaScript tools into your application. Some are more useful than others. And if you believe in proper UI, some should be avoided 99% of the time.
They can:
Now, implement this goodness (minus the React) into your Symfony projects with less JS and no BS required. Use the ones that improve your UX and skip any unnecessary UI.
Want to eliminate even more JavaScript? Read our article, Frontend Madness: SPAs, MPAs, PWAs, Decoupled, Hybrid, Monolithic, Libraries, Frameworks! WTF for your PHP backend?
We rate these SymfonyCast courses 10 out of 10.
It’s worth the investment. Plus, they are entertaining.
To learn about more advanced options, visit the repository @symfony/stimulus-bridge, the Node package that is responsible for a lot of the magic Stimulus JS brings to Symfony UX.
Happy coding Symfonistas!
Symfony Station covers the essential news in the Symfony, PHP, and Fediverse development communities with a focus on protecting democracy. Please use the button above to make a small donation to help cover our out-of-pocket costs. Our labor is provided free of charge to support the communities we write about.
Subscribe to The Payload, our weekly newsletter exploring the Symfony Universe.