symfony/stimulus-bundle
Symfony bundle that integrates Stimulus with Symfony and Symfony UX. Adds Twig stimulus_* helpers for controllers/actions/targets, supports AssetMapper, and provides a service to build Stimulus data attributes for use in templates and services.
Install the Bundle:
composer require symfony/stimulus-bundle
Ensure your config/bundles.php includes:
return [
// ...
Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],
];
Enable Stimulus in Twig:
Add the bundle to your config/packages/twig.php:
twig:
globals:
stimulus: '@stimulus'
First Use Case:
Create a Stimulus controller (e.g., assets/controllers/example_controller.js):
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
connect() {
console.log('Example controller connected!');
}
}
Use it in a Twig template:
<div {{ stimulus_controller('example') }}>
This element will trigger the Stimulus controller.
</div>
Verify Asset Pipeline:
Ensure assets/controllers.json is generated (AssetMapper) or your Webpack Encore config includes Stimulus controllers.
Controllers:
{{ stimulus_controller('modal', { 'target': 'modal' }) }}
Renders: data-controller="modal" data-modal-target="modal".
Actions:
{{ stimulus_action('modal#open') }}
Renders: data-action="modal#open->click".
Targets:
{{ stimulus_target('modal', 'closeButton') }}
Renders: data-modal-target="closeButton".
Use the StimulusHelper service in PHP to generate attributes dynamically:
$helper = $this->container->get('stimulus.helper');
$attributes = $helper->getControllerAttributes('modal', ['target' => 'modal']);
// Output: ['data-controller' => 'modal', 'data-modal-target' => 'modal']
symfony/ux-turbo-bundle for SPA-like navigation.
{{ stimulus_controller('turbo-frame', { 'target': 'frame' }) }}
connect() {
this.subscription = this.hub.subscribe('update', (event) => {
this.element.textContent = event.data;
});
}
Enable TypeScript controllers by configuring assets/controllers.json:
{
"controllers": [
"./assets/controllers/**/*_controller.{js,ts}"
]
}
Ensure assets/controllers.json excludes non-Stimulus files:
# config/packages/asset_mapper.yaml
framework:
assets:
excluded_patterns:
- '*/controllers.json'
Create modular controllers in assets/controllers/ and import them in templates:
{{ stimulus_controller('shared/modal') }}
Pass dynamic parameters to Stimulus actions:
{{ stimulus_action('modal#open', { 'id': post.id }) }}
Access in JavaScript:
open(event) {
const id = event.detail.id; // post.id
}
Use outlets for parent-child controller communication:
<div {{ stimulus_controller('parent') }}>
<div {{ stimulus_outlet('parent', 'child') }}></div>
</div>
// Parent controller
connect() {
this.childController = this.outlet('child');
}
Enable Symfony Profiler to inspect Stimulus controllers:
# config/packages/dev/stimulus.yaml
stimulus:
debug: true
Asset Pipeline Issues:
assets/controllers.json is generated and included in your app.js:
import './controllers/**/*_controller';
Case Sensitivity in Parameters:
stimulus_action are now camelCase (BC break in v2.13.0).
{{ stimulus_action('example#action', { 'bigCrocodile': 'value' }) }}
Access in JS as event.detail.bigCrocodile (not bigcrocodile).Windows Path Handling:
controllers.json or configure AssetMapper to normalize paths.Twig Function Deprecations:
ux_controller_link_tags() was removed in v3.0.0 (requires AssetMapper >=6.4).{{ stimulus_controller() }} directly or upgrade AssetMapper.TypeScript Module Conflicts:
type: "module" in package.json may break Stimulus imports."type": "commonjs" or ensure proper ESM imports:
import { Controller } from '@hotwired/stimulus';
Inspect Data Attributes: Use browser DevTools to verify rendered attributes:
<div data-controller="example" data-example-target="modal">
Log Stimulus Events: Add debug logs in controllers:
connect() {
console.log('Controller connected:', this.element.dataset);
}
Symfony Profiler: Enable Stimulus debugging in Profiler to track controller lifecycle:
framework:
profiler:
collectors:
stimulus: true
AssetMapper Debugging:
Check generated public/build/controllers.json for missing files:
php bin/console assets:install
Custom Twig Functions: Extend the bundle’s Twig environment:
// src/Twig/Extension/StimulusExtension.php
public function getFunctions() {
return [
new \Twig\TwigFunction('custom_stimulus', [$this, 'customStimulusFunction']),
];
}
Dynamic Controller Registration:
Override the StimulusHelper service to customize attribute generation:
# config/services.yaml
Symfony\UX\StimulusBundle\Helper\StimulusHelper:
arguments:
$controllerNamespace: 'App\\Stimulus'
Integration with Custom Packages:
Use the StimulusBundle as a foundation to build domain-specific controllers (e.g., app/controllers/admin/*_controller.js).
PHP Version Compatibility:
AssetMapper Exclusions:
Ensure excluded_patterns in asset_mapper.yaml matches your project structure:
framework:
assets:
excluded_patterns:
- '*/controllers.json' # Updated in v2.33
NPM Dependency Conflicts:
stimulus package versions.package.json:
"dependencies": {
"@hotwired/stimulus": "^3.2.1"
}
Caching Headaches:
php bin/console cache:clear
npm run build
How can I help you explore Laravel packages today?