Lists API
The lists
property of the system configuration object is where you define the data model, or schema, of your Keystone system. It accepts an object with list names as keys, and list()
configurations as values.
import { config, list } from '@keystone-6/core';export default config({lists: ({SomeListName: list({fields: { /* ... */ },access: { /* ... */ },ui: { /* ... */ },hooks: { /* ... */ },graphql: { /* ... */ },db: { /* ... */ },description: '...',isSingleton: false,defaultIsFilterable: false,defaultIsOrderable: false,}),/* ... */}),/* ... */});
This document will explain the configuration options which can be used with the list()
function.
Options:
isSingleton
: This flag, whentrue
changes the list to default to only supporting a single row. See Singletons for details.defaultIsFilterable
: This value sets the default value to use forisFilterable
for fields on this list.defaultIsOrderable
: This value sets the default value to use forisOrderable
for fields on this list.
fields
The fields
option defines the names, types, and configuration of the fields in the list. This configuration option takes an object with field names as keys and configured field types as values.
import { config, list } from '@keystone-6/core';import { text } from '@keystone-6/core/fields';export default config({lists: {SomeListName: list({fields: {someFieldName: text({ /* ... */ }),/* ... */},}),/* ... */},/* ... */});
For full details on the available field types and their configuration options please see the Fields API.
access
The access
option defines the Access Control rules for the list. These rules determine which of the CRUD (create, read, update, delete) operations users are allowed to perform.
See the Access Control API for full details on the available access control options.
ui
The ui
option controls how the list is displayed and interacted with in the Admin UI.
Options:
labelField
: Selects the field which will be used as the label column in the Admin UI. By default looks for a field called'label'
, then falls back to'name'
, then'title'
, and finally'id'
, which is guaranteed to exist.searchFields
: The fields used by the Admin UI when searching this list on the list view and in relationship fields. It is always possible to search by an id and'id'
should not be specified in this option. By default, thelabelField
is used if it has a stringcontains
filter, otherwise none.description
(default:undefined
): Sets the list description displayed in the Admin UI.isHidden
(default:false
): Controls whether the list is visible in the navigation elements of the Admin UI. Can be either a boolean value or an async function with an argument{ session, context }
that returns a boolean value.hideCreate
(default:false
): Controls whether thecreate
button is available in the Admin UI for this list. Can be either a boolean value or an async function with an argument{ session, context }
that returns a boolean value.hideDelete
(default:false
): Controls whether thedelete
button is available in the Admin UI for this list. Can be either a boolean value or an async function with an argument{ session, context }
that returns a boolean value.createView
: Controls the create view page of the Admin UI.defaultFieldMode
(default:'edit'
): Can be overridden by per-field values in thefield.ui.createView.fieldMode
config. See the Fields API for details. Can be one of['edit', 'hidden']
, or an async function with an argument{ session, context }
that returns one of['edit', 'hidden']
.
itemView
: Controls the item view page of the Admin UI.defaultFieldMode
(default:'edit'
): Can be overridden by per-field values in thefield.ui.itemView.fieldMode
config. See the Fields API for details. Can be one of['edit', 'read', 'hidden']
, or an async function with an argument{ session, context, item }
that returns one of['edit', 'read', 'hidden']
.
listView
: Controls the list view page of the Admin UI.defaultFieldMode
(default:'read'
): Controls the default mode of fields in the list view. Can be overridden by per-field values in thefield.ui.listView.fieldMode
config. See the Fields API for details. Can be one of['read', 'hidden']
, or an async function with an argument{ session, context }
that returns one of['read', 'hidden']
.initialColumns
(default: The first three fields defined in the list). A list of field names to display in columns in the list view. By default only the label column, as determined bylabelField
, is shown.initialSort
(default:undefined
): Sets the field and direction to be used to initially sort the data in the list view. Optionfield
is the name of the field to sort by, anddirection
is either'ASC'
or'DESC'
for ascending and descending sorting respectively. If undefined then data will be unsorted.pageSize
(default: lower of50
orgraphql.maxTake
): Sets the number of items to show per page in the list view.
label
: The label used to identify the list in navigation etc.singular
: The singular form of the list key. It is used in sentences likeAre you sure you want to delete this {singular}?
plural
: The plural form of the list key. It is used in sentences likeAre you sure you want to delete these {plural}?
path
: A path segment to identify the list in URLs. It must match the pattern/^[a-z-_][a-z0-9-_]*$/
.
import { config, list } from '@keystone-6/core';import { text } from '@keystone-6/core/fields`;export default config({lists: {SomeListName: list({fields: { name: text({ /* ... */ }) },ui: {labelField: 'name',searchFields: ['name', 'alternativeName'],description: '...',isHidden: ({ session, context }) => false,hideCreate: ({ session, context }) => false,hideDelete: ({ session, context }) => false,createView: {defaultFieldMode: ({ session, context }) => 'edit',},itemView: {defaultFieldMode: ({ session, context, item }) => 'edit',},listView: {defaultFieldMode: ({ session, context }) => 'read',initialColumns: ['name', /* ... */],initialSort: { field: 'name', direction: 'ASC' },pageSize: 50,},label: "Some List",singular: "Item",plural: "Items",path: 'some-list'},}),/* ... */},/* ... */});
hooks
The hooks
option defines hook functions for the list. Hooks allow you to execute code at different stages of the mutation lifecycle.
See the Hooks API for full details on the available hook options.
graphql
The graphql
config option allows you to configure certain aspects of the GraphQL API.
Options:
description
(default:undefined
): Sets the description of the associated GraphQL type in the generated GraphQL API documentation. Overrides the list-leveldescription
config option.plural
: (default: Pluralised list key, e.g.'Users'
): Overrides the name used in multiple mutations and queries (e.g.users()
,updateUsers()
, etc).maxTake
(default:undefined
): Allows you to specify the maximumtake
number for query operations on this list in the GraphQL API.cacheHint
(default:undefined
): Allows you to specify the dynamic cache control hints used for queries to this list.omit
(default:undefined
): Allows you to configure which parts of the CRUD API are autogenerated for your GraphQL API. This option accepts eithertrue
, or an object with the below fields. If you specifytrue
then the entire list, including its output type, will be omitted from the GraphQL API.omit.query
(default:false
): If set to true, the query operation will be omitted from the GraphQL API for this list.omit.create
(default:false
): If set to true, the create mutation will be omitted from the GraphQL API for this list.omit.update
(default:false
): If set to true, the update mutation will be omitted from the GraphQL API for this list.omit.delete
(default:false
): If set to true, the delete mutation will be omitted from the GraphQL API for this list.
import { config, list } from '@keystone-6/core';export default config({lists: {SomeListName: list({graphql: {description: '...',itemQueryName: '...',listQueryName: '...',maxTake: 100,cacheHint: { maxAge: 60, scope: 'PRIVATE' },omit: {query: true,create: true,update: true,delete: true,},},/* ... */}),/* ... */},/* ... */});
db
The db
config option allows you to configure certain aspects of the database connection specific to this list.
Options:
idField
(default:{ kind: "cuid" }
): The kind of id field to use, it can be one of:cuid
,uuid
orautoincrement
. The default across all lists can be changed at the root-leveldb.idField
config. If you are usingautoincrement
, you can also specifytype: 'BigInt'
on PostgreSQL and MySQL to use BigInts.map
: Adds a Prisma@@map
attribute to the Prisma model for this list which specifies a custom database table name for the list, instead of using the list key
import { config, list } from '@keystone-6/core';export default config({lists: {SomeListName: list({db: {idField: { kind: 'uuid' },map: 'table_name',},/* ... */}),/* ... */},/* ... */});
description
The description
option defines a string that will be used as a description in the Admin UI and GraphQL API docs. This option can be individually overridden by the graphql.description
or ui.description
options.
isSingleton
The isSingleton
flag changes a list to only have support for a single row with an id
of 1
.
With the flag set, when an item is created it is given an id
of 1
, and when an item is queried from a list, the GraphQL where
filter defaults to { id: '1' }
.
An example of when this might helpful is for editing data like your frontend configuration, when it wouldn't otherwise be checked into source control.
Abstracting singletons as a behavioural trait of lists instead of a distinct type helps developers build functions for lists without needing to know the underlying constraints, effectively ensuring that lists remain as functors.
Using GraphQL, to query a list named seoConfiguration
, with isSingleton
set, you can write any of the following queries
query {# singular (null or an item)seoConfiguration {titledescription}# plural (0 or 1 items)seoConfigurations {titledescription}}
In the Admin UI, lists with isSingleton
set do not have a list view, instead redirecting you to the item view page of the item with an id
of 1
.
The following additional constraints should be kept in mind when lists that have isSingleton
set —
- With
id: 1
injected into respective filters, theid
unique constraint will fail for create operations if an item already exists - You cannot have relationships (
ref: 'Settings'
), ifSettings
is a list withisSingleton
set - You can however, have relationship fields in the
Settings
list, like normal
Try out our Singleton Example to see it in action.
Related resources
Fields API Reference →
Defines the names, types, and configuration of Keystone fields. See all the fields and the configuration options they accept.
Config API Reference →
The API to configure all the parts of your Keystone system.
Example Project: Blog →
A basic Blog schema with Posts and Authors. Use this as a starting place for learning how to use Keystone. It’s also a starter for other feature projects.