Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion packages/admin/src/components/ContentEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,13 @@ export function ContentEditor({

// Update form and last saved state when item changes (e.g., after save or restore)
// Stringify the data for comparison since objects are compared by reference
//
// NOTE: item?.updatedAt is intentionally excluded from the dependency array.
// Including it caused a circular reset loop: autosave → server updates updatedAt →
// query refetch → this effect fires → form state resets to server values →
// user's in-progress edits are lost. By depending only on actual data/slug/status
// changes, the form only resets when content meaningfully changes (e.g., after
// discard draft or restore revision), not on every timestamp bump.
const itemDataString = React.useMemo(() => (item ? JSON.stringify(item.data) : ""), [item?.data]);
React.useEffect(() => {
if (item) {
Expand All @@ -274,7 +281,7 @@ export function ContentEditor({
}),
);
}
}, [item?.updatedAt, itemDataString, item?.slug, item?.status]);
}, [itemDataString, item?.slug, item?.status]);

const activeBylines = isNew ? (selectedBylines ?? []) : internalBylines;

Expand Down
6 changes: 4 additions & 2 deletions packages/admin/src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -621,8 +621,10 @@ function ContentEditPage() {
}) => updateContent(collection, id, { ...data, skipRevision: true }),
onSuccess: () => {
setLastAutosaveAt(new Date());
// Silently update the cache without full invalidation
void queryClient.invalidateQueries({ queryKey: ["content", collection, id] });
// Don't invalidate the query here — a refetch would trigger the
// form-reset useEffect in ContentEditor and overwrite any edits
// the user made between the autosave request and the refetch response.
// The cache refreshes naturally on manual save, navigation, or window refocus.
},
onError: (err) => {
toastManager.add({
Expand Down
Loading