Actions
Actions are JavaScript snippets that run in the builder, in response to something the
user does to your element. They exist for elements whose preview needs help: a slider that
has to be re-initialised when a slide is added, a script that measures its container, a
library that needs tearing down before its node is removed.
Nothing here affects the front end. Front-end JavaScript belongs in
Dependencies.
The seven events

The tab lists them as accordions, each with a count of how many actions you've added:
| Event | Fires when |
|---|---|
| on created element | An instance of your element is added to the page |
| on mounted element | An instance is mounted in the canvas — after its dependencies and server-side render have loaded |
| on activated element | The user selects the element |
| on property change | Any of the element's control values changes |
| on moved element | The element is moved in the tree |
| on before deleting element | Immediately before it's removed. Your last chance to clean up |
| on after deleted element | After it has been removed |
on property change and on mounted element carry nearly all real use. The first
re-syncs a JavaScript widget with the user's new settings; the second initialises it once
the DOM and any server-rendered markup exist.
Writing one
An action is a script plus two optional settings.
The script goes through the same two passes as an inline dependency. First it's rendered as
Twig against the element's current property values, so you can read controls directly:
const swiper = window.mySwipers['124'];
if (swiper) {
swiper.params.slidesPerView = {{ content.slider.slides_per_view|json_encode }};
swiper.update();
}
Then %%NAME%% placeholders are substituted. Four are available:
| Placeholder | Value |
|---|---|
124 |
The element instance's node id |
.bde-themeless-template-content-area-256146-124 |
A CSS selector matching this instance |
%%PARENTID%% |
The parent node's id |
%%PARENT_SELECTOR%% |
A selector matching the parent |
%%PARENTID%% and %%PARENT_SELECTOR%% are only populated for the delete events, where
the element itself is on its way out and the parent is what you still have.
As in dependencies, run every interpolated control value through |json_encode. It's the
same hazard: a control value dropped raw into a JavaScript literal breaks on the first
apostrophe anyone types.
The script is injected into the canvas document and re-run each time the event fires, so
write it to be safe to run repeatedly — check whether your instance already exists rather
than assuming a clean slate.
Dependencies and runForAllChildren
Each action can name dependencies, which Breakdance ensures are loaded in the canvas before
the script runs. That covers the case where a dependency group is conditional and its
condition has only just become true — the action would otherwise run against a library that
isn't there yet.
Run for all children propagates the action down the tree: the parent's action also fires
for events on any element nested inside it. This is how a container-shaped element stays in
sync when its children change — a tabs element re-measuring after a panel is edited, a
slider re-initialising when a slide is added. Without it, the parent hears nothing about its
children.
When you don't need actions
Most elements need none at all. Before adding one, check whether a simpler mechanism does
the job:
- The element just renders differently — that's HTML and CSS; the
builder re-renders Twig as the user types, with no help from you. - Server-rendered output is stale — that's the SSR list on
Property Paths, not an action. - A library needs initialising on the front end — that's an inline script on
Dependencies.
Actions are for the gap those leave: a stateful JavaScript object living in the builder
canvas that has to be told when something changed.