The Payload Config

Payload is a config-based, code-first CMS and application framework. The Payload Config is central to everything that Payload does, allowing for deep configuration of your application through a simple and intuitive API. The Payload Config is a fully-typed JavaScript object that can be infinitely extended upon.

Everything from your Database choice, to the appearance of the Admin Panel, is fully controlled through the Payload Config. From here you can define Fields, add Localization, enable Authentication, configure Access Control, and so much more.

The Payload Config is a payload.config.ts file typically located in the root of your project:

1
import { buildConfig } from 'payload'
2
3
export default buildConfig({
4
// Your config goes here
5
})

The Payload Config is strongly typed and ties directly into Payload's TypeScript codebase. This means your IDE (such as VSCode) will provide helpful information like type-ahead suggestions while you write your config.

Config Options

To author your Payload Config, first determine which Database you'd like to use, then use Collections or Globals to define the schema of your data.

Here is one of the simplest possible Payload configs:

1
import { buildConfig } from 'payload'
2
import { mongooseAdapter } from '@payloadcms/db-mongodb'
3
4
export default buildConfig({
5
secret: process.env.PAYLOAD_SECRET,
6
db: mongooseAdapter({
7
url: process.env.DATABASE_URI,
8
}),
9
collections: [
10
{
11
slug: 'pages',
12
fields: [
13
{
14
name: 'title',
15
type: 'text'
16
}
17
]
18
}
19
],
20
})

The following options are available:

OptionDescription
adminThe configuration options for the Admin Panel, including Custom Components, Live Preview, etc. More details.
binRegister custom bin scripts for Payload to execute.
editorThe Rich Text Editor which will be used by richText fields. More details.
db *The Database Adapter which will be used by Payload. More details.
serverURLA string used to define the absolute URL of your app. This includes the protocol, for example https://example.com. No paths allowed, only protocol, domain and (optionally) port.
collectionsAn array of Collections for Payload to manage. More details.
compatibilityCompatibility flags for earlier versions of Payload. More details.
globalsAn array of Globals for Payload to manage. More details.
corsCross-origin resource sharing (CORS) is a mechanism that accept incoming requests from given domains. You can also customize the Access-Control-Allow-Headers header. More details.
localizationOpt-in to translate your content into multiple locales. More details.
loggerLogger options, logger options with a destination stream, or an instantiated logger instance. More details.
graphQLManage GraphQL-specific functionality, including custom queries and mutations, query complexity limits, etc. More details.
cookiePrefixA string that will be prefixed to all cookies that Payload sets.
csrfA whitelist array of URLs to allow Payload to accept cookies from. More details.
defaultDepthIf a user does not specify depth while requesting a resource, this depth will be used. More details.
defaultMaxTextLengthThe maximum allowed string length to be permitted application-wide. Helps to prevent malicious public document creation.
maxDepthThe maximum allowed depth to be permitted application-wide. This setting helps prevent against malicious queries. Defaults to 10. More details.
indexSortableFieldsAutomatically index all sortable top-level fields in the database to improve sort performance and add database compatibility for Azure Cosmos and similar.
uploadBase Payload upload configuration. More details.
routesControl the routing structure that Payload binds itself to. More details.
emailConfigure the Email Adapter for Payload to use. More details.
debugEnable to expose more detailed error information.
telemetryDisable Payload telemetry by passing false. More details.
rateLimitControl IP-based rate limiting for all Payload resources. Used to prevent DDoS attacks, etc. More details.
hooksAn array of Root Hooks. More details.
pluginsAn array of Plugins. More details.
endpointsAn array of Custom Endpoints added to the Payload router. More details.
customExtension point for adding custom data (e.g. for plugins).
i18nInternationalization configuration. Pass all i18n languages you'd like the admin UI to support. Defaults to English-only. More details.
secret *A secure, unguessable string that Payload will use for any encryption workflows - for example, password salt / hashing.
sharpIf you would like Payload to offer cropping, focal point selection, and automatic media resizing, install and pass the Sharp module to the config here.
typescriptConfigure TypeScript settings here. More details.

* An asterisk denotes that a property is required.

Typescript Config

Payload exposes a variety of TypeScript settings that you can leverage. These settings are used to auto-generate TypeScript interfaces for your Collections and Globals, and to ensure that Payload uses your Generated Types for all Local API methods.

To customize the TypeScript settings, use the typescript property in your Payload Config:

1
import { buildConfig } from 'payload'
2
3
export default buildConfig({
4
// ...
5
typescript: {
6
// ...
7
}
8
})

The following options are available:

OptionDescription
autoGenerateBy default, Payload will auto-generate TypeScript interfaces for all collections and globals that your config defines. Opt out by setting typescript.autoGenerate: false. More details.
declareBy default, Payload adds a declare block to your generated types, which makes sure that Payload uses your generated types for all Local API methods. Opt out by setting typescript.declare: false.
outputFileControl the output path and filename of Payload's auto-generated types by defining the typescript.outputFile property to a full, absolute path.

Config Location

For Payload command-line scripts, we need to be able to locate your Payload Config. We'll check a variety of locations for the presence of payload.config.ts by default, including:

  1. The root current working directory
  2. The compilerOptions in your tsconfig*
  3. The dist directory*

* Config location detection is different between development and production environments. See below for more details.

Development Mode

In development mode, if the configuration file is not found at the root, Payload will attempt to read your tsconfig.json, and attempt to find the config file specified in the rootDir:

1
{
2
// ...
3
"compilerOptions": {
4
"rootDir": "src"
5
}
6
}

Production Mode

In production mode, Payload will first attempt to find the config file in the outDir of your tsconfig.json, and if not found, will fallback to the rootDor directory:

1
{
2
// ...
3
"compilerOptions": {
4
"outDir": "dist",
5
"rootDir": "src"
6
}
7
}

If none was in either location, Payload will finally check the dist directory.

Customizing the Config Location

In addition to the above automated detection, you can specify your own location for the Payload Config. This can be useful in situations where your config is not in a standard location, or you wish to switch between multiple configurations. To do this, Payload exposes an Environment Variable to bypass all automatic config detection.

To use a custom config location, set the PAYLOAD_CONFIG_PATH environment variable:

1
{
2
"scripts": {
3
"payload": "PAYLOAD_CONFIG_PATH=/path/to/custom-config.ts payload"
4
}
5
}

Telemetry

Payload collects completely anonymous telemetry data about general usage. This data is super important to us and helps us accurately understand how we're growing and what we can do to build the software into everything that it can possibly be. The telemetry that we collect also help us demonstrate our growth in an accurate manner, which helps us as we seek investment to build and scale our team. If we can accurately demonstrate our growth, we can more effectively continue to support Payload as free and open-source software. To opt out of telemetry, you can pass telemetry: false within your Payload Config.

For more information about what we track, take a look at our privacy policy.

Cross-origin resource sharing (CORS)

Cross-origin resource sharing (CORS) can be configured with either a whitelist array of URLS to allow CORS requests from, a wildcard string (*) to accept incoming requests from any domain, or a object with the following properties:

OptionDescription
originsEither a whitelist array of URLS to allow CORS requests from, or a wildcard string ('*') to accept incoming requests from any domain.
headersA list of allowed headers that will be appended in Access-Control-Allow-Headers.

Here's an example showing how to allow incoming requests from any domain:

1
import { buildConfig } from 'payload/config'
2
3
export default buildConfig({
4
// ...
5
cors: '*'
6
})

Here's an example showing how to append a new header (x-custom-header) in Access-Control-Allow-Headers:

1
import { buildConfig } from 'payload/config'
2
3
export default buildConfig({
4
// ...
5
cors: {
6
origins: ['http://localhost:3000']
7
headers: ['x-custom-header']
8
}
9
})

TypeScript

You can import types from Payload to help make writing your config easier and type-safe. There are two main types that represent the Payload Config, Config and SanitizedConfig.

The Config type represents a raw Payload Config in its full form. Only the bare minimum properties are marked as required. The SanitizedConfig type represents a Payload Config after it has been fully sanitized. Generally, this is only used internally by Payload.

1
import type { Config, SanitizedConfig } from 'payload'

Server vs. Client

The Payload Config only lives on the server and is not allowed to contain any client-side code. That way, you can load up the Payload Config in any server environment or standalone script, without having to use Bundlers or Node.js loaders to handle importing client-only modules (e.g. scss files or React Components) without any errors.

Behind the curtains, the Next.js-based Admin Panel generates a ClientConfig, which strips away any server-only code and enriches the config with React Components.

Compatibility flags

The Payload Config can accept compatibility flags for running the newest versions but with older databases. You should only use these flags if you need to, and should confirm that you need to prior to enabling these flags.

allowLocalizedWithinLocalized

Payload localization works on a field-by-field basis. As you can nest fields within other fields, you could potentially nest a localized field within a localized field—but this would be redundant and unnecessary. There would be no reason to define a localized field within a localized parent field, given that the entire data structure from the parent field onward would be localized.

By default, Payload will remove the localized: true property from sub-fields if a parent field is localized. Set this compatibility flag to true only if you have an existing Payload MongoDB database from pre-3.0, and you have nested localized fields that you would like to maintain without migrating.

Next

Collection Configs