Y-prosemirror missing doc attrs

The prosemirrorJSONToYDoc function removes all doc attrs on conversion. I think this is a bug. I have created a pen to demo the issue.

Am I missing config or is this a bug? Thanks for any help.

Hi @jstleger0,

a ProseMirror document doesn’t have attributes. A document is a fragment (only containing children, no attributes). But Node inherits from Fragment, so your code does run. However, it is not expected that the doc-attributes are synced.

Any Prosemirror Node can have attrs including state.doc (See: https://prosemirror.net/docs/ref/#model.Node). We have been using state.doc.attrs in our current operational transform implementation for a few years.

I wrote a post on it here… (It requires a custom step to set)

We use it to store document-level settings that we want to be collaborative (Shared between users).

At the moment when using yjs those attributes are lost and are set back to the defaults in the schema.

Hey @jstleger0, I didn’t know that you could add properties because the functions were basically missing in ProseMirror. As a result, Yjs won’t be able to sync attributes on the doc because it is synced to a Y.XmlFragment (which doesn’t allow attributes by definition).

If you want, you can open a ticket on the y-prosemirror repository to enable syncing of doc attributes. Currently, y-prosemirror expects a Y.XmlFragment to sync to a doc. Y.XmlFragment doesn’t allow attributes by definition. We could add a feature to sync attributes when Y.XmlElement is used as a data binding target. However, I’m not sure when I can get to this.

In the meantime, you can maybe use a Y.XmlElement as a target and set the attributes on Y.XmlElemnt manually. This is really easy as you just have to do yfragment.setAttribute('prop', 'val').

We are running into a lot of complexity with this… We are currently looking at adding a leaf node within the document to contain the doc attrs… so we can maintain functionality.


  doc: {
    content: `docattrs block+`,
    selectable: false,
  docattrs: {
    atom: true,
    defining: true,
    selectable: false,
    attrs: {
      somedata: { default: 0 },
  parawrapper: {
    defining: true,
    group: 'block',
    content: [...],

However, changing the schema is a very involved process within a collaborative system. Our current operational transforms will have to be remapped and reset and every service that consumes the document will need to be updated…

Is there a solution that we can work on with you? It would be great to get the doc node represented as a Y.XmlElement in the y-prosemirror implementation.

This is the last major hurdle for us taking YJS into production.