Create a UX bundle
Warning: You are browsing the documentation for Symfony 6.2, which is no longer maintained.
Read the updated version of this page for Symfony 7.3 (the current stable version).
Create a UX bundle
Tip
Before reading this, you may want to have a look at Best Practices for Reusable Bundles.
Here are a few tricks to make your bundle install as a UX bundle.
composer.json file
Your composer.json file must have the symfony-ux keyword:
1 2 3
{
"keywords": ["symfony-ux"]
}
Assets location
Your assets must be located in one of the following directories, with a package.json file so Flex can handle it
during install/update:
/assets(recommended)/Resources/assets/src/Resources/assets
package.json file
Your package.json file must contain a symfony config with controllers defined, and also add required packages
to the peerDependencies:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
{
"name": "@acme/feature",
"version": "1.0.0",
"symfony": {
"controllers": {
"slug": {
"main": "dist/controller.js",
"fetch": "eager",
"enabled": true,
"autoimport": {
"dist/bootstrap4-theme.css": false,
"dist/bootstrap5-theme.css": true
}
}
}
},
"peerDependencies": {
"@hotwired/stimulus": "^3.0.0",
"slugify": "^1.6.5"
}
}
In this case, the file located at [assets directory]/dist/controller.js will be exposed.
Tip
You can either write raw JS in this dist/controller.js file, or you can e.g. write your controller with
TypeScript and transpile it to JavaScript.
Here is an example to do so:
- Add the following to your
package.jsonfile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
{
"scripts": {
"build": "babel src --extensions .ts -d dist"
},
"devDependencies": {
"@babel/cli": "^7.20.7",
"@babel/core": "^7.20.12",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/preset-env": "^7.20.2",
"@babel/preset-typescript": "^7.18.6",
"@hotwired/stimulus": "^3.2.1",
"typescript": "^4.9.5"
}
}
- Run either
npm installoryarn installto install the new dependencies. - Write your Stimulus controller with TypeScript in
src/controller.ts. - Run
npm run buildoryarn run buildto transpile your TypeScript controller into JavaScript.
To use your controller in a template (e.g. one defined in your bundle) you can use it like this:
1 2 3 4 5 6 7 8 9 10
<div
{{ stimulus_controller('acme/feature/slug', { modal: 'my-value' }) }}
{#
will render:
data-controller="acme--feature--slug"
data-acme--feature--slug-modal-value="my-value"
#}
>
...
</div>
Don't forget to add symfony/stimulus-bundle:^2.9 as a composer dependency to use
Twig stimulus_* functions.
Tip
Controller Naming: In this example, the name of the PHP package is acme/feature and the name
of the controller in package.json is slug. So, the full controller name for Stimulus will be
acme--feature--slug, though with the stimulus_controller() function, you can use acme/feature/slug.
Each controller has a number of options in package.json file:
| Option | Description |
|---|---|
| enabled | Whether the controller should be enabled by default. |
| main | Path to the controller file. |
| fetch | How controller & dependencies are included when the page loads.
Use eager (default) to make controller & dependencies included in the JavaScript that's
downloaded when the page is loaded.
Use lazy to make controller & dependencies isolated into a separate file and only downloaded
asynchronously if (and when) the data-controller HTML appears on the page. |
| autoimport | List of files to be imported with the controller. Useful e.g. when there are several CSS styles depending on the frontend framework used (like Bootstrap 4 or 5, Tailwind CSS...). The value must be an object with files as keys, and a boolean as value for each file to set whether the file should be imported. |