Thinkmill / Thinkmill/keystatic
A stale local draft shadows the file on disk; saving in that state overwrites the real content
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 2.4k
- Forks
- 159
- Avg merge
- 21h 41m
- Merged PRs (30d)
- 2
Description
A stale local draft silently shadows the file on disk, and saving in that state overwrites the real content. With an array or blocks field this shows up as an empty list, so pressing Save wipes every item.
What happens
- Open a singleton in the admin, start an edit, do not save, navigate away. Keystatic keeps the draft.
- Come back to that singleton later — hours or days.
- The entry shows
Unsavedand renders the draft, not the file. If the draft was created before the file had content, the fields come up empty. - Pressing
Savewrites the draft over the file.
The toast "Restored draft from …" does appear, but it is easy to miss: it is transient, it sits in the corner, and it reads as informational rather than as a warning that what you are looking at is not what is on disk.
Where it bit us
A singleton with a fields.blocks list of five sections, all present in the yaml on disk. Opening it showed Unsaved and Empty list — Add the first item to see it here. The five sections were still in the file; the admin was showing a draft from an earlier session. Clicking Reset brought them back immediately.
An editor who does not know what Reset does would reasonably conclude the content was lost and start re-entering it — or press Save, which is the destructive option and the one that looks like it fixes things.
Suggestions
Any one of these would help:
- Expire drafts after some period. There is currently no TTL that I can find; a draft appears to live in IndexedDB indefinitely.
- Make the restored-draft state persistent rather than a toast — for example a banner above the form with a "discard draft" action, so the state is visible at the moment someone reaches for Save.
- Offer a config option to turn local drafts off entirely, for projects that do not want them.
The last one is what we looked for first. CommonConfig exposes locale, cloud and ui; there does not appear to be a way to disable draft persistence.
Versions
@keystatic/core0.6.4,@keystatic/astro5.1.0- Astro 6.4.8, React 19.2.0, local storage mode
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing local draft persistence in IndexedDB and the restored-draft flow around CommonConfig, including the existing "Restored draft from …" toast and Reset action. Compare the admin form's displayed draft with the file on disk for singleton fields.blocks data. Done means stale drafts cannot silently overwrite current content, with a visible recovery or disable option covering the reported case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- content, frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100