This.on('change:attributes:type', this.handleTypeChange) do not support array type
Listeners don't see deep changes so you have to create a new array in that case
Read full answer below โQuestion
GrapesJS version
- I confirm to use the latest version of GrapesJS
What browser are you using?
Chrome 108.0.5359.125
Reproducible demo link
https://codesandbox.io/s/frosty-darkness-7po7xl
Describe the bug
How to reproduce the bug?
- use myBlock
- click test button
What is the expected behavior?
this.on("change:list1", this.handleList1Change);
work every time
What is the current behavior? this.on("change:list1", this.handleList1Change); only run once
If is necessary to execute some code in order to reproduce the bug, paste it here below:
import grapesjs from "grapesjs";
const myPlugin = function (editor, opts) {
editor.TraitManager.addType("listitem", {
createInput({ trait }) {
this.traitName = trait.get("name");
this.items = [
{
id: 1,
title: "Item1"
}
];
const el = document.createElement("div");
el.innerHTML = '<button type="button">test</button>';
el.querySelector("button").addEventListener("click", (ev) =>
this.onChange(ev)
);
return el;
},
onEvent({ elInput, component, event }) {
// console.log(event);
const itemLength = this.items.length;
this.items.push({
id: itemLength,
title: `Item${itemLength}`
});
component.set(this.traitName, this.items);
console.log("onEvent", this.items);
},
onUpdate({ elInput, component }) {}
});
editor.DomComponents.addType("myComponent", {
isComponent: (el) => {
if (el && el.classList && el.classList.contains("widget1")) {
return true;
}
},
model: {
defaults: {
attributes: { class: "widget1" },
components: `<div>test</div>`,
traits: [
{
type: "listitem",
name: "list1",
label: "list1",
changeProp: 1
}
]
},
init() {
this.on("change:list1", this.handleList1Change);
},
handleList1Change() {
console.log("onChange", this.attributes.list1);
}
},
view: {}
});
editor.BlockManager.add("myBlock", {
label: "MyBlock",
content: { type: "myComponent" },
select: true
});
};
const editor = grapesjs.init({
container: "#gjs",
fromElement: 1,
storageManager: { type: 0 },
plugins: [myPlugin]
});
editor.on("component:selected", function (component) {
editor.Panels.getButton("views", "open-tm").set({ active: true });
});

Code of Conduct
- I agree to follow this project's Code of Conduct
Answers (3)
Listeners don't see deep changes so you have to create a new array in that case
component.set(this.traitName, [...this.items]);
Thanks @artf. I use JSON.stringify and JSON.parse to deal my data.
Thanks for reporting this, @chaegumi.
Great question about this.on('change:attributes:type', this.handleTypeChange) do not support array type. The recommended approach with Components is to use the event-driven API.
Start here:
- Check the GrapesJS documentation for your specific module
- Look for the
on()event listener method - Most operations can be achieved by listening to editor and component events
Common patterns:
// Listen for changes
editor.on('change', () => console.log('something changed'));
// Component lifecycle
editor.on('component:mount', (c) => console.log('component ready', c));
editor.on('component:update', (c) => console.log('component updated', c));
If you're still stuck:
- Share a minimal CodeSandbox reproduction
- Include what you've already tried
- Mention your GrapesJS version
- The community is here to help!
Related Questions and Answers
Continue research with similar issue discussions.
Issue #4145
0.18.3 text editing not triggering for link > text components
GrapesJS version [x] I confirm to use the latest version of GrapesJS What browser are you using? Chrome 99 Reproducible demo link https://c...
Issue #5263
Deleting a component without deleting its corresponding style, will adding new components later cause style conflicts?
GrapesJS version [X] I confirm to use the latest version of GrapesJS What browser are you using? latest version of Chrome Reproducible demo...
Issue #4897
component:styleUpdate / component:styleUpdate:propertyName not fired
GrapesJS version [X] I confirm to use the latest version of GrapesJS What browser are you using? Edge 109.0.1518.70 Reproducible demo link...
Issue #5019
Can't set preview mode on editor init when using loadProjectData()
GrapesJS version [X] I confirm to use the latest version of GrapesJS What browser are you using? Chrome v111 Reproducible demo link https:/...
Paid Plugins That Match This Issue
Curated by issue keywords and label relevance to help you ship faster.
Loading paid plugin recommendations...
Check the open-source GrapesJS plugins on GitHub or run a quick search in our free catalog.
Browse free plugins โPremium plugins ship with support, regular updates, and production-ready features โ save days of integration work.
Browse premium plugins โRelated tutorials
In-depth guides on the same topic.
Tutorial
Find the Right GrapesJS Plugin in Seconds: Smarter Discovery Is Live
We're shipping a set of discovery upgrades. New label filters, a proper compatibility switch for GrapesJS vs Studio, one-click and a smarter sort bar.
Tutorial
GrapesJS vs Webflow vs Tilda: What to Choose for Your Business in 2026
Choosing the right website platform in 2026 is no longer just about building a site
Tutorial
GJS Market 2.0 - Donations, Tracking, Labels and Better Product Discovery
Weโve rolled out a new set of GrapesJS marketplace updates across GJS Market, focused on improving how creators distribute products
Browse Plugin Categories
Jump directly to plugin category pages on the marketplace.