---
title: Query Presets
label: Overview
order: 10
desc: Query Presets allow you to save and share filters, columns, and sort orders for your collections.
keywords:
---

Query Presets allow you to save and share filters, columns, and sort orders for your [Collections](../configuration/collections). This is useful for reusing common or complex filtering patterns and/or sharing them across your team.

Each Query Preset is saved as a new record in the database under the `payload-query-presets` collection. This allows for an endless number of preset configurations, where the users of your app define the presets that are most useful to them, rather than being hard coded into the Payload Config.

Within the [Admin Panel](../admin/overview), Query Presets are applied to the List View. When enabled, new controls are displayed for users to manage presets. Once saved, these presets can be loaded up at any time and optionally shared with others.

To enable Query Presets on a Collection, use the `enableQueryPresets` property in your [Collection Config](../configuration/collections):

```ts
import type { CollectionConfig } from 'payload'

export const MyCollection: CollectionConfig = {
  // ...
  // highlight-start
  enableQueryPresets: true,
  // highlight-end
}
```

## Config Options

While not required, you may want to customize the behavior of Query Presets to suit your needs, such as add custom labels or access control rules.

Settings for Query Presets are managed on the `queryPresets` property at the root of your [Payload Config](../configuration/overview):

```ts
import { buildConfig } from 'payload'

const config = buildConfig({
  // ...
  // highlight-start
  queryPresets: {
    // ...
  },
  // highlight-end
})
```

The following options are available for Query Presets:

| Option        | Description                                                                                                                     |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `access`      | Used to define custom collection-level access control that applies to all presets. [More details](#access-control).             |
| `constraints` | Used to define custom document-level access control that apply to individual presets. [More details](#document-access-control). |
| `labels`      | Custom labels to use for the Query Presets collection.                                                                          |

## Access Control

Query Presets are subject to the same [Access Control](../access-control/overview) as the rest of Payload. This means you can use the same patterns you are already familiar with to control who can read, update, and delete presets.

Access Control for Query Presets can be customized in two ways:

1. [Collection Access Control](#collection-access-control): Applies to all presets. These rules are not controllable by the user and are statically defined in the config.
2. [Document Access Control](#document-access-control): Applies to each individual preset. These rules are controllable by the user and are saved to the document.

### Collection Access Control

Collection-level access control applies to _all_ presets within the Query Presets collection. Users cannot control these rules, they are written statically in your config.

To add Collection Access Control, use the `queryPresets.access` property in your [Payload Config](../configuration/overview):

```ts
import { buildConfig } from 'payload'

const config = buildConfig({
  // ...
  queryPresets: {
    // ...
    // highlight-start
    access: {
      read: ({ req: { user } }) =>
        user ? user?.roles?.some((role) => role === 'admin') : false,
      update: ({ req: { user } }) =>
        user ? user?.roles?.some((role) => role === 'admin') : false,
    },
    // highlight-end
  },
})
```

This example restricts all Query Presets to users with the role of `admin`.

<Banner type="warning">
  **Note:** Custom access control will override the defaults on this collection,
  including the requirement for a user to be authenticated. Be sure to include
  any necessary checks in your custom rules unless you intend on making these
  publicly accessible.
</Banner>

### Document Access Control

You can also define access control rules that apply to each specific preset. Users have the ability to define and modify these rules on the fly as they manage presets. These are saved dynamically in the database on each document.

When a user manages a preset, document-level access control options will be available to them in the Admin Panel for each operation.

By default, Payload provides a set of sensible defaults for all Query Presets, but you can customize these rules to suit your needs:

- **Only Me**: Only the user who created the preset can read, update, and delete it.
- **Everyone**: All users can read, update, and delete the preset.
- **Specific Users**: Only select users can read, update, and delete the preset.

#### Custom Access Control

You can augment the default access control rules with your own custom rules. This can be useful for creating more complex access control patterns that the defaults don't provide, such as for RBAC.

Adding custom access control rules requires:

1. A label to display in the dropdown
2. A set of fields to conditionally render when that option is selected
3. A function that returns the access control rules for that option

To do this, use the `queryPresets.constraints` property in your [Payload Config](../configuration/overview).

```ts
import { buildConfig } from 'payload'

const config = buildConfig({
  // ...
  queryPresets: {
    // ...
    // highlight-start
    constraints: {
      read: [
        {
          label: 'Specific Roles',
          value: 'specificRoles',
          fields: [
            {
              name: 'roles',
              type: 'select',
              hasMany: true,
              options: [
                { label: 'Admin', value: 'admin' },
                { label: 'User', value: 'user' },
              ],
            },
          ],
          access: ({ req: { user } }) => ({
            'access.read.roles': {
              in: [user?.roles],
            },
          }),
        },
      ],
      // highlight-end
    },
  },
})
```

In this example, we've added a new option called `Specific Roles` that allows users to select from a list of roles. When this option is selected, the user will be prompted to select one or more roles from a list of options. The access control rule for this option is that the user operating on the preset must have one of the selected roles.

<Banner type="warning">
  **Note:** Payload places your custom fields into the `access[operation]` field
  group, so your rules will need to reflect this.
</Banner>

The following options are available for each constraint:

| Option   | Description                                                              |
| -------- | ------------------------------------------------------------------------ |
| `label`  | The label to display in the dropdown for this constraint.                |
| `value`  | The value to store in the database when this constraint is selected.     |
| `fields` | An array of fields to render when this constraint is selected.           |
| `access` | A function that determines the access control rules for this constraint. |
