This PR makes three major changes to the codebase: 1. [Component Paths](#component-paths) Instead of importing custom components into your config directly, they are now defined as file paths and rendered only when needed. That way the Payload config will be significantly more lightweight, and ensures that the Payload config is 100% server-only and Node-safe. Related discussion: https://github.com/payloadcms/payload/discussions/6938 2. [Client Config](#client-config) Deprecates the component map by merging its logic into the client config. The main goal of this change is for performance and simplification. There was no need to deeply iterate over the Payload config twice, once for the component map, and another for the client config. Instead, we can do everything in the client config one time. This has also dramatically simplified the client side prop drilling through the UI library. Now, all components can share the same client config which matches the exact shape of their Payload config (with the exception of non-serializable props and mapped custom components). 3. [Custom client component are no longer server-rendered](#custom-client-components-are-no-longer-server-rendered) Previously, custom components would be server-rendered, no matter if they are server or client components. Now, only server components are rendered on the server. Client components are automatically detected, and simply get passed through as `MappedComponent` to be rendered fully client-side. ## Component Paths Instead of importing custom components into your config directly, they are now defined as file paths and rendered only when needed. That way the Payload config will be significantly more lightweight, and ensures that the Payload config is 100% server-only and Node-safe. Related discussion: https://github.com/payloadcms/payload/discussions/6938 In order to reference any custom components in the Payload config, you now have to specify a string path to the component instead of importing it. Old: ```ts import { MyComponent2} from './MyComponent2.js' admin: { components: { Label: MyComponent2 }, }, ``` New: ```ts admin: { components: { Label: '/collections/Posts/MyComponent2.js#MyComponent2', // <= has to be a relative path based on a baseDir configured in the Payload config - NOT relative based on the importing file }, }, ``` ### Local API within Next.js routes Previously, if you used the Payload Local API within Next.js pages, all the client-side modules are being added to the bundle for that specific page, even if you only need server-side functionality. This `/test` route, which uses the Payload local API, was previously 460 kb. It is now down to 91 kb and does not bundle the Payload client-side admin panel anymore. All tests done [here](https://github.com/payloadcms/payload-3.0-demo/tree/feat/path-test) with beta.67/PR, db-mongodb and default richtext-lexical: **dev /admin before:**  **dev /admin after:**  --- **dev /test before:**  **dev /test after:**  --- **build before:**  **build after::**  ### Usage of the Payload Local API / config outside of Next.js This will make it a lot easier to use the Payload config / local API in other, server-side contexts. Previously, you might encounter errors due to client files (like .scss files) not being allowed to be imported. ## Client Config Deprecates the component map by merging its logic into the client config. The main goal of this change is for performance and simplification. There was no need to deeply iterate over the Payload config twice, once for the component map, and another for the client config. Instead, we can do everything in the client config one time. This has also dramatically simplified the client side prop drilling through the UI library. Now, all components can share the same client config which matches the exact shape of their Payload config (with the exception of non-serializable props and mapped custom components). This is breaking change. The `useComponentMap` hook no longer exists, and most component props have changed (for the better): ```ts const { componentMap } = useComponentMap() // old const { config } = useConfig() // new ``` The `useConfig` hook has also changed in shape, `config` is now a property _within_ the context obj: ```ts const config = useConfig() // old const { config } = useConfig() // new ``` ## Custom Client Components are no longer server rendered Previously, custom components would be server-rendered, no matter if they are server or client components. Now, only server components are rendered on the server. Client components are automatically detected, and simply get passed through as `MappedComponent` to be rendered fully client-side. The benefit of this change: Custom client components can now receive props. Previously, the only way for them to receive dynamic props from a parent client component was to use hooks, e.g. `useFieldProps()`. Now, we do have the option of passing in props to the custom components directly, if they are client components. This will be simpler than having to look for the correct hook. This makes rendering them on the client a little bit more complex, as you now have to check if that component is a server component (=> already has been rendered) or a client component (=> not rendered yet, has to be rendered here). However, this added complexity has been alleviated through the easy-to-use `<RenderMappedComponent />` helper. This helper now also handles rendering arrays of custom components (e.g. beforeList, beforeLogin ...), which actually makes rendering custom components easier in some cases. ## Misc improvements This PR includes misc, breaking changes. For example, we previously allowed unions between components and config object for the same property. E.g. for the custom view property, you were allowed to pass in a custom component or an object with other properties, alongside a custom component. Those union types are now gone. You can now either pass an object, or a component. The previous `{ View: MyViewComponent}` is now `{ View: { Component: MyViewComponent} }` or `{ View: { Default: { Component: MyViewComponent} } }`. This dramatically simplifies the way we read & process those properties, especially in buildComponentMap. We can now simply check for the existence of one specific property, which always has to be a component, instead of running cursed runtime checks on a shared union property which could contain a component, but could also contain functions or objects.   - [x] I have read and understand the [CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md) document in this repository. --------- Co-authored-by: PatrikKozak <patrik@payloadcms.com> Co-authored-by: Paul <paul@payloadcms.com> Co-authored-by: Paul Popus <paul@nouance.io> Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com> Co-authored-by: James <james@trbl.design>
257 lines
17 KiB
Plaintext
257 lines
17 KiB
Plaintext
---
|
|
title: The Payload Config
|
|
label: Overview
|
|
order: 10
|
|
desc: The Payload Config is central to everything that Payload does, from adding custom React components, to modifying collections, controlling localization and much more.
|
|
keywords: overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
|
---
|
|
|
|
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](../database/overview) choice, to the appearance of the [Admin Panel](../admin/overview), is fully controlled through the Payload Config. From here you can define [Fields](../fields/overview), add [Localization](./localization), enable [Authentication](../authentication/overview), configure [Access Control](../access-control/overview), and so much more.
|
|
|
|
The Payload Config is a `payload.config.ts` file typically located in the root of your project:
|
|
|
|
```ts
|
|
import { buildConfig } from 'payload'
|
|
|
|
export default buildConfig({
|
|
// Your config goes here
|
|
})
|
|
```
|
|
|
|
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.
|
|
|
|
<Banner type="success">
|
|
<strong>Tip:</strong>
|
|
The location of your Payload Config can be customized. [More details](#customizing--automating-config-location-detection).
|
|
</Banner>
|
|
|
|
## Config Options
|
|
|
|
To author your Payload Config, first determine which [Database](../database/overview) you'd like to use, then use [Collections](./collections) or [Globals](./globals) to define the schema of your data.
|
|
|
|
Here is one of the simplest possible Payload configs:
|
|
|
|
```ts
|
|
import { buildConfig } from 'payload'
|
|
import { mongooseAdapter } from '@payloadcms/db-mongodb'
|
|
// import { postgresAdapter } from '@payloadcms/db-postgres'
|
|
|
|
export default buildConfig({
|
|
secret: process.env.PAYLOAD_SECRET,
|
|
db: mongooseAdapter({
|
|
url: process.env.DATABASE_URI,
|
|
}),
|
|
collections: [
|
|
{
|
|
slug: 'pages',
|
|
fields: [
|
|
{
|
|
name: 'title',
|
|
type: 'text'
|
|
}
|
|
]
|
|
}
|
|
],
|
|
})
|
|
```
|
|
|
|
<Banner type="success">
|
|
<strong>Note:</strong>
|
|
For a more complex example, see the [Public Demo](https://github.com/payloadcms/public-demo) source code on GitHub, or the [Templates](https://github.com/payloadcms/payload/tree/main/templates) and [Examples](https://github.com/payloadcms/payload/tree/main/examples) directories in the Payload repository.
|
|
</Banner>
|
|
|
|
The following options are available:
|
|
|
|
| Option | Description |
|
|
|----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
| **`admin`** | The configuration options for the Admin Panel, including Custom Components, Live Preview, etc. [More details](../admin/overview#admin-options). |
|
|
| **`bin`** | Register custom bin scripts for Payload to execute. |
|
|
| **`editor`** | The Rich Text Editor which will be used by `richText` fields. [More details](../rich-text/overview). |
|
|
| **`db`** \* | The Database Adapter which will be used by Payload. [More details](../database/overview). |
|
|
| **`serverURL`** | A 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. |
|
|
| **`collections`** | An array of Collections for Payload to manage. [More details](./collections). |
|
|
| **`globals`** | An array of Globals for Payload to manage. [More details](./globals). |
|
|
| **`cors`** | Cross-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](#cors). |
|
|
| **`localization`** | Opt-in to translate your content into multiple locales. [More details](./localization). |
|
|
| **`graphQL`** | Manage GraphQL-specific functionality, including custom queries and mutations, query complexity limits, etc. [More details](../graphql/overview#graphql-options). |
|
|
| **`cookiePrefix`** | A string that will be prefixed to all cookies that Payload sets. |
|
|
| **`csrf`** | A whitelist array of URLs to allow Payload to accept cookies from. [More details](../authentication/overview#csrf-protection). |
|
|
| **`defaultDepth`** | If a user does not specify `depth` while requesting a resource, this depth will be used. [More details](../queries/depth). |
|
|
| **`defaultMaxTextLength`** | The maximum allowed string length to be permitted application-wide. Helps to prevent malicious public document creation. |
|
|
| **`maxDepth`** | The maximum allowed depth to be permitted application-wide. This setting helps prevent against malicious queries. Defaults to `10`. [More details](../queries/depth). |
|
|
| **`indexSortableFields`** | Automatically index all sortable top-level fields in the database to improve sort performance and add database compatibility for Azure Cosmos and similar. |
|
|
| **`upload`** | Base Payload upload configuration. [More details](../upload/overview#payload-wide-upload-options). |
|
|
| **`routes`** | Control the routing structure that Payload binds itself to. [More details](../admin/overview#root-level-routes). |
|
|
| **`email`** | Configure the Email Adapter for Payload to use. [More details](../email/overview). |
|
|
| **`debug`** | Enable to expose more detailed error information. |
|
|
| **`telemetry`** | Disable Payload telemetry by passing `false`. [More details](#telemetry). |
|
|
| **`rateLimit`** | Control IP-based rate limiting for all Payload resources. Used to prevent DDoS attacks, etc. [More details](../production/preventing-abuse#rate-limiting-requests). |
|
|
| **`hooks`** | An array of Root Hooks. [More details](../hooks/overview). |
|
|
| **`plugins`** | An array of Plugins. [More details](../plugins/overview). |
|
|
| **`endpoints`** | An array of Custom Endpoints added to the Payload router. [More details](../rest-api/overview#custom-endpoints). |
|
|
| **`custom`** | Extension point for adding custom data (e.g. for plugins). |
|
|
| **`i18n`** | Internationalization configuration. Pass all i18n languages you'd like the admin UI to support. Defaults to English-only. [More details](./i18n). |
|
|
| **`secret`** \* | A secure, unguessable string that Payload will use for any encryption workflows - for example, password salt / hashing. |
|
|
| **`sharp`** | If you would like Payload to offer cropping, focal point selection, and automatic media resizing, install and pass the Sharp module to the config here. |
|
|
| **`typescript`** | Configure TypeScript settings here. [More details](#typescript). |
|
|
|
|
_\* An asterisk denotes that a property is required._
|
|
|
|
<Banner type="warning">
|
|
<strong>Note:</strong>
|
|
Some properties are removed from the client-side bundle. [More details](../admin/components#accessing-the-payload-config).
|
|
</Banner>
|
|
|
|
|
|
### 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](../configuration/collections) and [Globals](../configuration/globals), and to ensure that Payload uses your [Generated Types](../typescript/overview) for all [Local API](../local-api/overview) methods.
|
|
|
|
To customize the TypeScript settings, use the `typescript` property in your Payload Config:
|
|
|
|
```ts
|
|
import { buildConfig } from 'payload'
|
|
|
|
export default buildConfig({
|
|
// ...
|
|
typescript: { // highlight-line
|
|
// ...
|
|
}
|
|
})
|
|
```
|
|
|
|
The following options are available:
|
|
|
|
| Option | Description |
|
|
| --------------- | --------------------- |
|
|
| **`autoGenerate`** | By 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](../typescript/overview). |
|
|
| **`declare`** | By 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`. |
|
|
| **`outputFile`** | Control 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
|
|
1. The `compilerOptions` in your `tsconfig`*
|
|
1. The `dist` directory*
|
|
|
|
_\* Config location detection is different between development and production environments. See below for more details._
|
|
|
|
<Banner type="warning">
|
|
<strong>Important:</strong>
|
|
Ensure your `tsconfig.json` is properly configured for Payload to auto-detect your config location. If if does not exist, or does not specify the proper `compilerOptions`, Payload will default to the current working directory.
|
|
</Banner>
|
|
|
|
**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`:
|
|
|
|
```json
|
|
{
|
|
// ...
|
|
// highlight-start
|
|
"compilerOptions": {
|
|
"rootDir": "src"
|
|
}
|
|
// highlight-end
|
|
}
|
|
```
|
|
|
|
**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:
|
|
|
|
```json
|
|
{
|
|
// ...
|
|
// highlight-start
|
|
"compilerOptions": {
|
|
"outDir": "dist",
|
|
"rootDir": "src"
|
|
}
|
|
// highlight-end
|
|
}
|
|
```
|
|
|
|
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](..environment-variables) to bypass all automatic config detection.
|
|
|
|
To use a custom config location, set the `PAYLOAD_CONFIG_PATH` environment variable:
|
|
|
|
```json
|
|
{
|
|
"scripts": {
|
|
"payload": "PAYLOAD_CONFIG_PATH=/path/to/custom-config.ts payload"
|
|
}
|
|
}
|
|
```
|
|
|
|
<Banner type="info">
|
|
<strong>Tip:</strong>
|
|
`PAYLOAD_CONFIG_PATH` can be either an absolute path, or path relative to your current working directory.
|
|
</Banner>
|
|
|
|
## 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](/privacy).
|
|
|
|
## 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:
|
|
|
|
| Option | Description |
|
|
| --------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| **`origins`** | Either a whitelist array of URLS to allow CORS requests from, or a wildcard string (`'*'`) to accept incoming requests from any domain. |
|
|
| **`headers`** | A 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:
|
|
|
|
```ts
|
|
import { buildConfig } from 'payload/config'
|
|
|
|
export default buildConfig({
|
|
// ...
|
|
cors: '*' // highlight-line
|
|
})
|
|
```
|
|
|
|
Here's an example showing how to append a new header (`x-custom-header`) in `Access-Control-Allow-Headers`:
|
|
|
|
```ts
|
|
import { buildConfig } from 'payload/config'
|
|
|
|
export default buildConfig({
|
|
// ...
|
|
// highlight-start
|
|
cors: {
|
|
origins: ['http://localhost:3000']
|
|
headers: ['x-custom-header']
|
|
}
|
|
// highlight-end
|
|
})
|
|
```
|
|
|
|
## 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.
|
|
|
|
```ts
|
|
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.
|