payloadcms / payloadcms/payload
Switching list-view tabs (All / By Folder / Trash) wipes the collection's saved preferences (columns, sort, limit)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 44.8k
- Forks
- 4.2k
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 53
Description
Describe the Bug
DefaultListViewTabs saves which sub-view is active with:
// @payloadcms/ui/dist/elements/DefaultListViewTabs/index.js (3.87.0, ~line 41)
await setPreference(`collection-${collectionConfig.slug}`, {
listViewType: newViewType
});
setPreference defaults to merge = false (providers/Preferences/index.js, line 76), so this call replaces the entire collection-<slug> preference record with { listViewType } — silently destroying the user's saved columns, sort, limit and any other list preferences, every time they click between "All " and "By Folder" (or Trash).
We confirmed the mechanism by reading the payload-preferences record before/after a tab click: a record containing { limit, columns, listViewType } is reduced to { listViewType: "folders" } by a single click on the By Folder pill.
This hits folder-enabled upload collections hardest: users add the Folder column, visit By Folder to organise, come back — and their column setup is gone. Non-technical editors experience this as "my columns keep randomly disappearing".
Reproduction steps
- Any collection with
folders: true(ortrash: true) so the tab pills render. - In the list view, add a column via the Columns panel (e.g. Folder). Confirm the
collection-<slug>preference record now containscolumns. - Click By Folder, then All .
- The added column is gone; the preference record contains only
{ listViewType }.
Expected / Actual
- Expected: switching tabs remembers the active sub-view without touching other saved preferences.
- Actual: every tab switch replaces the whole preference record.
Proposed fix
Pass the existing merge flag (one argument):
await setPreference(`collection-${collectionConfig.slug}`, {
listViewType: newViewType
- });
+ }, true);
Note the same handler is also inlined (minified) in dist/exports/client/index.js, which is what some import sites actually execute — the fix needs to land in the source so both builds pick it up. We've been running this exact change in production via a pnpm patch with no side effects.
Environment
- Payload: 3.86.0 (found), verified still present in 3.87.0 source
- @payloadcms/db-postgres, @payloadcms/next
- Next.js: 16.2.11
- Node: 22.14.0
- pnpm 10.30.3, macOS / Vercel
Contributor guide
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 with the DefaultListViewTabs handler and providers/Preferences/index.js, then reproduce the tab switch while inspecting the payload-preferences record. Check the source path that generates the mentioned dist/exports/client/index.js build. Done means switching tabs preserves columns, sort, limit, and other existing preferences while updating listViewType.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nextjs, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100