Skip to content

Add guide for custom Stimulus controllers#1764

Open
falkgeist wants to merge 2 commits into
contao:mainfrom
falkgeist:falkgeist-stimulus-controllers-bundle
Open

Add guide for custom Stimulus controllers#1764
falkgeist wants to merge 2 commits into
contao:mainfrom
falkgeist:falkgeist-stimulus-controllers-bundle

Conversation

@falkgeist
Copy link
Copy Markdown
Contributor

No description provided.

@zoglo
Copy link
Copy Markdown
Member

zoglo commented May 21, 2026

Unsure if I like having this in the documentation since people don't really need to use stimulus but can use mutation observers. Especially not within the dev as it's not part of the Contao API.

@falkgeist
Copy link
Copy Markdown
Contributor Author

falkgeist commented May 21, 2026

I see your point.

The problem with mutation observers is, that any changes to the DOM based on the observers might in turn trigger Stimulus' observer 🤪. But that is a different issue, imho.

The issue described in the first paragraph is very real though, if you ask me:

Custom backend JS with listeners to the DOMContentLoaded event is only triggered on 'real' page loads, not Turbo navigation.

Implementing your own controller is not the definitive fix for that (there's your mentioned mutation observers or also Turbo events), but it does mitigate the issue.

- /guides/adding-stimulus-controllers/
---

Since Contao 5 now uses Turbo and Stimulus for the backend, sometimes it might not be enough to register JS assets for the backend as described under [Adding Backend assets][AddingBackendAssets], especially when listening for the `DOMContentLoaded` event.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of Stimulus by the Contao back end is irrelevant here - only the use of Turbo matters. But even that is not completely correct. Even the legacy JavaScript of the Contao back end might add, remove or modify existing DOM nodes, so it is always a good idea to write JavaScript that can handle any kind of DOM manipulation.


Since Contao 5 now uses Turbo and Stimulus for the backend, sometimes it might not be enough to register JS assets for the backend as described under [Adding Backend assets][AddingBackendAssets], especially when listening for the `DOMContentLoaded` event.

In this case it might be necessary to add a custom Stimulus controller.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not necessary, but Stimulus makes it way easier to implement what I mentioned above.

Comment on lines +42 to +43


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

import MyCustomWidgetController from "./controllers/my-custom-widget-controller";

const application = Application.start();
application.register("my-vendor-prefix--my-custom-widget", MyCustomWidgetController);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
application.register("my-vendor-prefix--my-custom-widget", MyCustomWidgetController);
application.register('my-vendor-prefix--my-custom-widget', MyCustomWidgetController);

Comment on lines +57 to +68
// Call the beforeCache() function on all controllers implementing it. This
// allows controllers to tear down things before the page gets put into cache.
// Note that Stimulus' disconnect() function will not fire at this point and
// thus cannot be used for this task.
document.documentElement.addEventListener('turbo:before-cache', (e) => {
for (const controller of application.controllers) {
if ('function' === typeof controller.beforeCache) {
controller.beforeCache(e);
}
}
});
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we really need to include this bit here. I think it would be better to keep it short and simple and just refer to the internals here. Whether you want something to be executed before the page is being put into the cache really depends on the controller. Ideally a simple controller should not need to care.

@m-vo wdyt?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants