Dynamic values in toDOM

I’m looking on adding IDs to heading for easier linking (GitHub style). I thought this would be easy by just modifying toDOM method for the header schema to calculate the value from text content:

heading: {
    attrs: {
      level: {
        default: 1,
    content: "inline*",
    group: "block",
    defining: true,
    draggable: false,
    parseDOM: HEADING_LEVELS.map(level => ({
      tag: `h${level}`,
      attrs: { level },
    toDOM: node => {
      const id = `h${node.attrs.level}-${slugify(node.textContent)}`;
      return [`h${node.attrs.level}`, { id }, 0];

While the id calculation works inside function, the value inserted into id is always h2-and lacks the dynamic part. I think I’m missing something obvious on how HTML serialization works but unsure what it is.

toDOM isn’t going to be called again when the content of a node changes, so it’s not suitable for this. A node view could do it (those get their update method called when the node changes), or if this is only relevant in non-editable output, you could just write your own rendering function.

@marijn Thanks for the tip, I’ll try this with a nodeview instead

This post maybe of help: How I can attach attribute with dynamic value when new paragraph is inserted?