Skip to content

internationalized-array: defaultLanguages patches on mount, so opening a form persists an empty draft #1825

Description

@joaodotwork

Describe the bug

With defaultLanguages configured, opening a new-document form is enough to persist a draft,
even if the editor types nothing and navigates away.

The plugin applies its defaults from an effect that patches the document on mount. In Sanity a
patch is what brings a draft into existence, so the act of rendering the form creates one. The
resulting document contains only the seeded identity rows — note there is no value key anywhere:

{
  "_id": "drafts.X6w3bu3dUaiAMZ8jI4zmao",
  "_type": "project",
  "title":       [{ "_key": "en", "_type": "internationalizedArrayStringValue",             "language": "en" }],
  "description": [{ "_key": "en", "_type": "internationalizedArraySimplePortableTextValue", "language": "en" }]
}

In our Studio these accumulate as "Untitled" documents, because the desk lands on a
new-document form on its own after you delete or unpublish something — so an editor doing routine
cleanup leaves a draft behind each time without ever choosing to create one. We had collected ten
before noticing.

The cost is not only clutter. These drafts are untitled, image-less and untagged, so any
dataset-wide quality query counts them: they were being reported as documents missing a
description, missing images, missing every taxonomy field, and so on — a content-completeness
signal reading them as real work in progress.

To Reproduce

internationalizedArray({
  languages: [
    { id: 'en', title: 'English' },
    { id: 'pt', title: 'Portuguese' },
  ],
  defaultLanguages: ['en'],
  fieldTypes: ['string', 'text'],
})
  1. Open any document type with an internationalized field via Create new.
  2. Type nothing. Navigate away.
  3. Query the dataset with the raw perspective:
    *[_id in path("drafts.**")] — a new draft is there, holding only the seeded rows.

Watching the network while the form mounts shows the /data/mutate/ request that creates it.

Expected behavior

Rendering a form should not write. The seeded language rows are a presentation default — somewhere
to type — so ideally they would exist in the form value without being patched to the document until
the editor actually enters content.

Which versions of Sanity are you using?

  • sanity-plugin-internationalized-array 5.1.3
  • sanity 6.8.0

Workaround

Removing defaultLanguages stops it: with no defaults to apply, the effect makes no patch and no
draft appears until the editor types. Confirmed by driving the create form in a browser and counting
drafts either side — zero /data/mutate/ requests afterwards.

The cost is that localized fields no longer start with a row to type into. buttonLocations
defaults to ['field'], which puts an Add button on every localized field; adding 'document'
gives a single document-level control instead, which keeps it to one deliberate click per document.
That combination has been a reasonable trade for us, but it is a trade rather than a fix.

Possibly related

#527 reports a different symptom of what may be the same mechanism — defaultLanguages rows
becoming non-removable, blocking publish when a required sub-field is empty. Both come down to the
plugin enforcing its defaults against the stored document rather than the form state, so a change
there might address both. Filing separately since the observable problem is different.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions