You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add createEntityRecord for local‑only drafts in @wordpress/core‑data #74462
There is no createEntityRecord action in @wordpress/core-data, which blocks a local-first UX. The only available path is saveEntityRecord, which writes to the database immediately and forces cleanup if the user cancels.
A createEntityRecord action would allow creating a local-only entity record in the store, editing it, and saving only when the user confirms.
For instance, DataViews/DataForm is well-suited for list + form flows, but new-item creation cannot be done without persisting to the database. This prevents:
Admin page with a Books list rendered via DataViews
Book form rendered via DataForm
“New book (in-memory)” action that would use createEntityRecord
Current workaround: saveEntityRecord (draft saved immediately)
This means that the user must save data to the database before updating the entity.
CleanShot.2026-01-08.at.16.24.22.mp4
Expected behavior
createEntityRecord creates a local-only draft record in the store without persisting to the database.
The draft can be updated via editEntityRecord.
saveEntityRecord (or saveEditedEntityRecord) persists the draft and returns the real ID from WordPress.
Ideal experience
A local-only draft should be possible via createEntityRecord, and then updated with editEntityRecord until the user explicitly saves. The draft ID is temporary; WordPress assigns the real ID on save.
const{ dispatch }=wp.data;constdraft=dispatch('core').createEntityRecord('postType','book',{title: 'New book',status: 'draft',meta: {book_author: ''}});// Update the draft locally.dispatch('core').editEntityRecord('postType','book',draft.id,{title: 'Updated title',meta: {book_author: 'New author'},});// Persist only when the user confirms.awaitdispatch('core').saveEntityRecord('postType','book',draft);
Would we be able to query these local-only drafts via getEntityRecords? Mostly curious if the new API would allow us to do some sort of optimistic updates.
For example, when adding a new note, it needs to complete a round trip before we can display it to the user, which creates a bad UX, especially on slow connections.
Would we be able to query these local-only drafts via getEntityRecords? Mostly curious if the new API would allow us to do some sort of optimistic updates.
Interesting! I think this should be possible, and we could expose it as an opt-in option.
The drawback to local drafts is the risk of losing data if the browser tab is closed. I think WordPress usually uses autodrafts for this purpose, to represent something that's a temporary draft but saved.
In-memory items bring a lot of broader concerns. For example, do we need to remind the user to save if they try navigating away and how do features like 'parent' post work if the parent is only in-memory?
Not saying I'm against the idea, but the scope might be bigger than anticipated.
The drawback to local drafts is the risk of losing data if the browser tab is closed. I think WordPress usually uses autodrafts for this purpose, to represent something that's a temporary draft but saved.
I think that this issue should be handled by the consumer of the @wordpress/core-data. The consumer can check if a in-memory entity is present, and if it is, present the standard browser confirmation dialog when the user attempts to navigate away.
In-memory items bring a lot of broader concerns. For example, do we need to remind the user to save if they try navigating away and how do features like 'parent' post work if the parent is only in-memory?
Thanks for this context! I agree with you. I think that we should iterate and see how it goes. For now, potentially we can use unlock/lock to ensure that this API is used only across Gutenberg packages (and collect all the limitations, including this one). What do you think?
I think that this issue should be handled by the consumer of the @wordpress/core-data.
It has impacts on the broader ecosystem in core. Perhaps it's not too much of a concern if it's kept private. But if it's usable by extenders they can implement their own entities that are 'staged', and the problem is all the core gutenberg code that needs to be updated to ensure these staged entities are represented and work correctly in WordPress.
I guess the question would be, is that a workload you're willing to undertake?
One use-case we have for this in Core (there's an issue about it), is that right now when you add "tags" to a post, they are created as tags. So if you make a typo and remove that tag before saving, the tag with typo was actually saved.
The drawback to local drafts is the risk of losing data if the browser tab is closed. I think WordPress usually uses autodrafts for this purpose, to represent something that's a temporary draft but saved.
I think that this issue should be handled by the consumer of the @wordpress/core-data.
It has impacts on the broader ecosystem in core. Perhaps it's not too much of a concern if it's kept private. But if it's usable by extenders they can implement their own entities that are 'staged', and the problem is all the core gutenberg code that needs to be updated to ensure these staged entities are represented and work correctly in WordPress.
I agree with @talldan here that this is a risk that's worth considering. And we know of many cases when users have actually lost data because autosaves didn't trigger on time, were triggered earlier, or just didn't finish on time. Also, autosaves work only with post types, so by design, they're not a solution that works for all entities.
I wonder if we can treat the storage mechanism as an implementation detail and therefore something that can be configured. Yes, it might make sense that sometimes we store the drafts in memory, but perhaps we might want to store them in local storage or session storage, or even some remote storage? It would be useful to have control over this, so we can implement different variants of persistence storage, potentially registered and supported by plugins.
Also, if we consider that we'd go in the direction of implementing a mechanism to store the data locally, it creates exciting opportunities for building an offline-first experience in WordPress.
Another use case from Notes: preserving unsent note and reply drafts (#73473). They're a good fit for local-only records, but there are a few requirements:
Never synced. editEntityRecord passes edits to the sync manager, and comments are synced when RTC is enabled. A draft shouldn't reach other collaborators before it's submitted.
Not dirty. Drafts shouldn't show up in __experimentalGetDirtyEntityRecords, so they stay out of the save panel, the unsaved changes warning, and the site editor's Save.
No undo levels. Typing a note shouldn't mix with block edits in the undo history.
@Mamaduka given these three requirements, these feel more like local state and not local only entities that should live in core-data. What benefit core-data brings for these?
Activity
Mamaduka commentedon Jan 8, 2026
Thanks for the proposal, @gigitux!
Would we be able to query these local-only drafts via
getEntityRecords? Mostly curious if the new API would allow us to do some sort of optimistic updates.For example, when adding a new note, it needs to complete a round trip before we can display it to the user, which creates a bad UX, especially on slow connections.
gigitux commentedon Jan 8, 2026
Interesting! I think this should be possible, and we could expose it as an opt-in option.
talldan commentedon Jan 12, 2026
The drawback to local drafts is the risk of losing data if the browser tab is closed. I think WordPress usually uses autodrafts for this purpose, to represent something that's a temporary draft but saved.
In-memory items bring a lot of broader concerns. For example, do we need to remind the user to save if they try navigating away and how do features like 'parent' post work if the parent is only in-memory?
Not saying I'm against the idea, but the scope might be bigger than anticipated.
gigitux commentedon Jan 12, 2026
I think that this issue should be handled by the consumer of the
@wordpress/core-data. The consumer can check if a in-memory entity is present, and if it is, present the standard browser confirmation dialog when the user attempts to navigate away.Thanks for this context! I agree with you. I think that we should iterate and see how it goes. For now, potentially we can use
unlock/lockto ensure that this API is used only across Gutenberg packages (and collect all the limitations, including this one). What do you think?I'm working on an initial PR here: #74497
talldan commentedon Jan 15, 2026
It has impacts on the broader ecosystem in core. Perhaps it's not too much of a concern if it's kept private. But if it's usable by extenders they can implement their own entities that are 'staged', and the problem is all the core gutenberg code that needs to be updated to ensure these staged entities are represented and work correctly in WordPress.
I guess the question would be, is that a workload you're willing to undertake?
youknowriad commentedon Jan 22, 2026
One use-case we have for this in Core (there's an issue about it), is that right now when you add "tags" to a post, they are created as tags. So if you make a typo and remove that tag before saving, the tag with typo was actually saved.
tyxla commentedon Feb 6, 2026
I agree with @talldan here that this is a risk that's worth considering. And we know of many cases when users have actually lost data because autosaves didn't trigger on time, were triggered earlier, or just didn't finish on time. Also, autosaves work only with post types, so by design, they're not a solution that works for all entities.
I wonder if we can treat the storage mechanism as an implementation detail and therefore something that can be configured. Yes, it might make sense that sometimes we store the drafts in memory, but perhaps we might want to store them in local storage or session storage, or even some remote storage? It would be useful to have control over this, so we can implement different variants of persistence storage, potentially registered and supported by plugins.
tyxla commentedon Feb 6, 2026
Also, if we consider that we'd go in the direction of implementing a mechanism to store the data locally, it creates exciting opportunities for building an offline-first experience in WordPress.
Mamaduka commentedon Sep 30, 2026
Another use case from Notes: preserving unsent note and reply drafts (#73473). They're a good fit for local-only records, but there are a few requirements:
editEntityRecordpasses edits to the sync manager, and comments are synced when RTC is enabled. A draft shouldn't reach other collaborators before it's submitted.__experimentalGetDirtyEntityRecords, so they stay out of the save panel, the unsaved changes warning, and the site editor's Save.youknowriad commentedon Sep 30, 2026
@Mamaduka given these three requirements, these feel more like local state and not local only entities that should live in core-data. What benefit core-data brings for these?
Mamaduka commentedon Sep 30, 2026
@youknowriad, yeah, you're right. Notes just need "fancy" local state/cache.
Mostly a single source of truth for data, but without optimistic updates, it's probably not worth it.