---
title: "Admin Panel — User Preferences"
aliases: [payload-preferences, usePreferences, admin-preferences]
tags: [payloadcms, admin, preferences, react, hooks]
sources: [raw/admin__preferences.md]
created: 2026-05-15
updated: 2026-05-15
---

## Overview

Payload persists user preferences per-user across sessions and devices via a built-in `payload-preferences` collection. Preferences are tied to the authenticated user identity.

## Built-in Preferences (out of the box)

- Collection List View — active columns and their order
- Last active [[wiki/payloadcms/admin-panel-overview|Locale]]
- Collapsed state of `blocks`, `array`, and `collapsible` fields
- Last-known state of the `Nav` component

## Database Schema

Payload auto-creates a `payload-preferences` collection. Each document:

| Field | Description |
|-------|-------------|
| `id` | Unique preference ID |
| `key` | String key identifying the preference |
| `user.value` | ID of the user who owns this preference |
| `user.relationTo` | Slug of the collection the user belongs to |
| `value` | Any JSON-serializable shape |
| `createdAt` / `updatedAt` | Timestamps |

## API Access

Preferences are exposed via both REST and GraphQL APIs:
- REST: `/api/payload-preferences`
- GraphQL: see preferences queries in the GraphQL schema

## `usePreferences` Hook

Only usable inside Admin Panel React components (client-side). Import from `@payloadcms/ui`.

```tsx
import { usePreferences } from '@payloadcms/ui'

const { getPreference, setPreference } = usePreferences()
```

### `getPreference(key: string): Promise<any>`

Returns the stored value for the given key, or `null` if not set.

### `setPreference(key: string, value: any): Promise<void>`

Persists any JSON-serializable value under the given key for the current user.

## Usage Pattern

```tsx
'use client'
import { usePreferences } from '@payloadcms/ui'
import { useEffect, useState, useCallback } from 'react'

const PREF_KEY = 'my-component-state'

export function MyComponent() {
  const { getPreference, setPreference } = usePreferences()
  const [state, setState] = useState(null)

  // Load on mount
  useEffect(() => {
    getPreference(PREF_KEY).then(setState)
  }, [getPreference])

  // Save on change
  const update = useCallback((value) => {
    setState(value)
    setPreference(PREF_KEY, value)
  }, [setPreference])

  return <div>...</div>
}
```

## Use Cases

- **Color picker** — remember last used colors
- **Custom Nav** — persist accordion collapsed/expanded state
- **Recently accessed docs** — shortcuts on the Dashboard
- **Any editor UX state** — table sort, panel widths, filter presets

## Key Takeaways

- All preferences are **per-user** — Payload resolves the user automatically from the auth session
- Storage is in a Mongo/Postgres collection — preferences survive page reloads, new sessions, and different devices
- `usePreferences` is **admin-only** — do not use it in front-end public components
- Key namespace your preferences (e.g. `my-plugin:last-colors`) to avoid collisions with Payload internals
- `value` can be any JSON shape — arrays, objects, primitives all work

## Related

- [[wiki/payloadcms/admin-panel-overview|Admin Panel Overview]]
- [[wiki/tech-patterns/_index|Tech Patterns — Payload CMS]]
