JavaScript in SDC Components
When to Use
Use when adding interactive behavior to Single Directory Components (Drupal core feature since 10.3).
Decision
Place JavaScript file in component directory following naming convention. Drupal automatically creates library and attaches JS when component renders. Use standard Drupal.behaviors pattern for initialization.
Pattern
File structure:
components/button/
├── button.component.yml
├── button.twig
├── button.css
└── button.js # Automatically discovered
Component JavaScript (button.js):
(function (Drupal, once) {
'use strict';
Drupal.behaviors.buttonComponent = {
attach(context) {
// Target component specifically
once('button-component', '[data-component="button"]', context).forEach(function (element) {
// Component initialization
element.addEventListener('click', function(e) {
element.classList.toggle('is-active');
});
});
},
detach(context, settings, trigger) {
if (trigger === 'unload') {
// Component cleanup
}
}
};
})(Drupal, once);
Accessing component via data attribute (button.twig):
<button{{ attributes.addClass('button').setAttribute('data-component', 'button') }}>
{{ label }}
</button>
Library auto-generated: Drupal creates library as sdc/THEME_OR_MODULE--COMPONENT and attaches automatically.
Common Mistakes
- Wrong: Manually creating library for SDC JS → Right: Let Drupal auto-discover
- Why: Drupal does this automatically, creates duplication
- Wrong: Class-based selectors for targeting → Right: Use data attributes
- Why: Class-based selectors conflict with styling, break encapsulation
- Wrong: Global selectors in component JS → Right: Target specific component instances
- Why: Breaks component reusability, affects other instances
- Wrong: Forgetting context parameter → Right: Always use context
- Why: Breaks when multiple component instances on page
See Also
- Drupal.behaviors Pattern - Component initialization
- Reference: Using Single Directory Components
- Reference: SDC in Core
- Reference: Anatomy of SDC