The Symfony UX Initiative & Packages
Tip
Check out live demos of Symfony UX at https://ux.symfony.com!
Symfony UX is an initiative and set of libraries to seamlessly integrate JavaScript tools into your application. For example, want to render a chart with Chart.js? Use UX Chart.js to build the chart in PHP. The JavaScript is handled for you automatically.
Behind the scenes, the UX packages leverage Stimulus: a small, but powerful library for binding JavaScript functionality to elements on your page.
Installing Symfony UX
Before you install any specific UX library, make sure you've installed Webpack Encore.
If you already have it installed, make sure you have an
assets/bootstrap.js
file (this initializes Stimulus & the UX packages),
an assets/controllers.json
file (this controls the 3rd party UX packages that
you've installed) and .enableStimulusBridge('./assets/controllers.json')
in
your webpack.config.js
file. If these are missing, try upgrading the
symfony/webpack-encore-bundle
Flex recipe. See
Upgrading Flex Recipes.
All Symfony UX Packages
- ux-autocomplete: Transform
EntityType
,ChoiceType
or any<select>
element into an Ajax-powered autocomplete field (see demo) - ux-chartjs: Easy charts with Chart.js (see demo)
- ux-cropperjs: Form Type and tools for cropping images (see demo)
- ux-dropzone: Form Type for stylized "drop zone" for file uploads (see demo)
- ux-lazy-image: Optimize Image Loading with BlurHash (see demo)
- ux-live-component: Build Dynamic Interfaces with Zero JavaScript (see demo)
- ux-notify: Send server-sent native notification with Mercure (see demo)
- ux-react: Render React component from Twig (see demo)
- ux-swup: Integration with Swup (see demo)
- ux-turbo: Integration with Turbo Drive for a single-page-app experience (see demo)
- ux-twig-component: Build Twig Components Backed by a PHP Class (see demo)
- ux-typed: Integration with Typed (see demo)
- ux-vue: Render Vue component from Twig (see demo)
- ux-svelte: Render Svelte component from Twig.
Stimulus Tools around the World
Because Stimulus is used by developers outside of Symfony, many tools exist beyond the UX packages:
- stimulus-use: Add composable behaviors to your Stimulus controllers, like debouncing, detecting outside clicks and many other things.
- stimulus-components A large number of pre-made Stimulus controllers, like for Copying to clipboard, Sortable, Popover (similar to tooltips) and much more.
How does Symfony UX Work?
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. For example:
1 2 3 4 5 6
{
"devDependencies": {
"...": "",
"@symfony/ux-chartjs": "file:vendor/symfony/ux-chartjs/assets"
}
}
This gives you a real Node package (e.g. @symfony/ux-chartjs
) that, instead
of being downloaded, points directly to files that already live in your vendor/
directory.
The Flex recipe will usually also update your assets/controllers.json
file
to add a new Stimulus controller to your app. For example:
1 2 3 4 5 6 7 8 9 10 11
{
"controllers": {
"@symfony/ux-chartjs": {
"chart": {
"enabled": true,
"fetch": "eager"
}
}
},
"entrypoints": []
}
Finally, your assets/bootstrap.js
file - working with the @symfony/stimulus-bridge -
package will automatically register:
- All files in
assets/controllers/
as Stimulus controllers; - And all controllers described in
assets/controllers.json
as Stimulus controllers.
The end result: you install a package, and you instantly have a Stimulus
controller available! In this example, it's called
@symfony/ux-chartjs/chart
. Well, technically, it will be called
symfony--ux-chartjs--chart
. However, you can pass the original name
into the {{ stimulus_controller() }}
function from WebpackEncoreBundle, and
it will normalize it:
1 2 3 4
<div {{ stimulus_controller('@symfony/ux-chartjs/chart') }}>
<!-- will render as: -->
<div data-controller="symfony--ux-chartjs--chart">
Lazy Controllers
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.
Sometimes you may have a controller that is only used on some pages, or maybe
only in your admin area. In that case, you can make the controller "lazy". When
a controller is lazy, it is not downloaded on initial page load. Instead, as
soon as an element appears on the page matching the controller (e.g.
<div data-controller="hello">
), the controller - and anything else it imports -
will be lazyily-loaded via Ajax.
To make one of your custom controllers lazy, add a special comment on top:
1 2 3 4 5 6
import { Controller } from '@hotwired/stimulus';
/* stimulusFetch: 'lazy' */
export default class extends Controller {
// ...
}
To make a third-party controller lazy, in assets/controllers.json
, set
fetch
to lazy
.
Note
If you write your controllers using TypeScript, make sure
removeComments
is not set to true
in your TypeScript config.
More Advanced Setup
To learn about more advanced options, read about @symfony/stimulus-bridge, the Node package that is responsible for a lot of the magic.