Compare commits

..

302 Commits

Author SHA1 Message Date
Elliot DeNolf
0533e7f5db chore(release): v3.0.0-beta.93 [skip ci] 2024-08-27 14:16:30 -04:00
Paul
23c5ef428d fix: bugs in versions UI with perPage, pagination and diffs not showing for tabs. publish button no longer double saves when using keyboard (#7889)
Fixes:
- issue with publish button double saving on keyboard command
- versions diffs not showing if fields are tabs
https://github.com/payloadcms/payload/issues/7860
- navigation on versions not working for perPage and pagination
2024-08-27 17:45:30 +00:00
Alessio Gravili
f046a04510 fix(richtext-lexical): dependency checker suggesting incorrect version (#7888)
Fixes this:
https://discord.com/channels/967097582721572934/1278031296970625190/1278031652089757818
2024-08-27 17:17:19 +00:00
Elliot DeNolf
4cda7d2363 chore(release): v3.0.0-beta.92 [skip ci] 2024-08-27 09:44:02 -04:00
Elliot DeNolf
ea48cfbfe9 feat: implement info command (#7882)
Implements `info` command similar to Next.js.

`pnpm payload info` will output info in this format:

```
Binaries:
  Node: 18.20.2
  npm: 10.5.0
  Yarn: 1.22.19
  pnpm: 9.7.0
Relevant Packages:
  payload: 3.0.0-beta.91
  next: 15.0.0-canary.104
  @payloadcms/db-mongodb: 3.0.0-beta.91
  @payloadcms/db-postgres: 3.0.0-beta.91
  @payloadcms/email-nodemailer: 3.0.0-beta.91
  @payloadcms/graphql: 3.0.0-beta.91
  @payloadcms/next/utilities: 3.0.0-beta.91
  @payloadcms/plugin-cloud: 3.0.0-beta.91
  @payloadcms/richtext-lexical: 3.0.0-beta.91
  @payloadcms/richtext-slate: 3.0.0-beta.91
  @payloadcms/translations: 3.0.0-beta.91
  @payloadcms/ui/shared: 3.0.0-beta.91
  react: 19.0.0-rc-06d0b89e-20240801
  react-dom: 19.0.0-rc-06d0b89e-20240801
Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.6.0: Mon Jul 29 21:13:04 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T6020
  Available memory (MB): 32768
  Available CPU cores: 12
 ```
2024-08-27 01:41:39 +00:00
Paul
1aeb912762 fix(templates): website live preview and code block (#7881) 2024-08-26 23:42:45 +00:00
Paul
ce2cb35d71 fix(plugin-seo): remove dependency on import from payload/next package (#7879) 2024-08-26 22:40:38 +00:00
Paul
d3ec68ac2f fix: error when closing the live preview popup window (#7878) 2024-08-26 22:33:56 +00:00
Paul
05bf52aac3 fix(templates): website bug fixes for slug generation and form builder and adds support for strictNullChecks: true (#7877) 2024-08-26 22:10:09 +00:00
Jacob Fletcher
fed7f2fa5b fix: sanitizes modifyResponseHeaders from client config (#7876) 2024-08-26 21:50:29 +00:00
James Mikrut
686b0865b2 fix: exports richtext-slate useSlatePlugin (#7875)
## Description

exports `useSlatePlugin` for `richtext-slate`
2024-08-26 17:21:25 -04:00
Alessio Gravili
dfb4c8eb4c feat: add nextjs and react version checks to dependency checker (#7868) 2024-08-26 17:19:14 -04:00
Alessio Gravili
ad7a387e19 feat(richtext-lexical): more lenient url validation, URL-encode invalid urls on save (#7870)
Fixes https://github.com/payloadcms/payload/issues/7477

This simplifies validation to the point where it only errors on spaces.
Actual validation is then used in beforeChange, which then automatically
url encodes the input if it doesn't pass
2024-08-26 15:33:29 -04:00
Elliot DeNolf
d05be016ce ci(scripts): emoji release notes 2024-08-23 16:25:50 -04:00
Elliot DeNolf
ec3bb71e7c chore(release): v3.0.0-beta.91 [skip ci] 2024-08-23 16:13:30 -04:00
Elliot DeNolf
825d8b83d1 feat(templates): add vercel postgres template (#7841)
- docs: add db-vercel-postgres info
- feat: update template variations
2024-08-23 15:17:26 -04:00
Alessio Gravili
83022f6d55 feat: enable react compiler for @payloadcms/next package (#7839)
also upgrades esbuild and react compiler packages
2024-08-23 18:01:21 +00:00
Alessio Gravili
4bbc593dc5 chore: hide node deprecation warnings in monorepo (#7837) 2024-08-23 12:33:21 -04:00
Jacob Fletcher
03440f5eca fix(next): properly 404s not found documents (#7833) 2024-08-23 14:59:03 +00:00
Elliot DeNolf
0fa6611260 fix: trim down accepted args of getPayloadHMR (#7834)
`getPayloadHMR`'s arg type was accepting unnecessary args that did not
do anything. This was leading to confusion.

This PR trims down the accepted type.

Fixes #7832
2024-08-23 14:54:20 +00:00
Tylan Davis
a2d68f84e1 chore(richtext-*): improved rich text editor styles and interaction (#7817)
## Description

- Improves the standard typography styles of the rich text editors.
- Improve styles of Lexical relationship, inline-relationship, upload,
and blocks features.
- Improves drag and drop interaction for Lexical.
- Adds a dark mode style for Lexical inline toolbar, floating link editor,
and slash menu.

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

<!-- Please delete options that are not relevant. -->

- [x] Chore (non-breaking change which does not add functionality)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-23 14:50:53 +00:00
Jarrod Flesch
49c0709fed fix: collapsible toggle hover stacking issue (#7812) 2024-08-23 08:51:10 -04:00
Elliot DeNolf
350a4a0718 build(deps): update turborepo (#7827)
Updates turbo to v2.
2024-08-23 03:00:21 +00:00
Alessio Gravili
6349cd42e9 feat(richtext-lexical): improve upload and relationship node types (#7822)
Fixes https://github.com/payloadcms/payload/issues/7808. The types are
now accurate. Previously, they would assume that upload and relationship
nodes are never populated
2024-08-22 22:05:45 +00:00
Alessio Gravili
c2b2f10676 fix: weaken JsonObject type to allow types from payload-types being assigned to it (#7815)
This fixes that type in the website template:
3d86bf1974/templates/website/src/app/components/RichText/serialize.tsx (L24)

Now, JsonObject still ensures that only objects can be passed, but it's
weak enough to allow non-dynamic types like the ones we generate in
payload-types.

The "JSON" part of this type has no meaning anymore, as it does allow
objects with functions now. However, we can still use it to signal to
the user that this should be JSON-serializable. It's more clear than
just using Record<string, unknown>
2024-08-22 20:24:58 +00:00
Paul
95ebead464 feat(ui): add styling for no docs and clear all on hasmany upload (#7816) 2024-08-22 18:54:35 +00:00
Jacob Fletcher
3eed8b11cb fix(ui): relationship field "add new" button styling (#7814) 2024-08-22 14:55:36 +00:00
Dan Ribbens
404008dc4e chore: fix dev importmap for windows (#7811) 2024-08-22 09:55:55 -04:00
Elliot DeNolf
c7c6fca537 chore(eslint): remove fixable from no-imports-from-self [skip ci] 2024-08-22 09:36:17 -04:00
Ritsu
9de3ffdcfe chore(ui): expose useCollapsible hook (#7807)
Exposes `useCollapsible` hook from `@payloadcms/ui`
2024-08-22 04:11:18 +00:00
Alessio Gravili
1eefb12070 fix(richtext-lexical): slate => lexical migrator improvements (#7802) 2024-08-22 00:09:43 -04:00
Elliot DeNolf
2d8b752ef2 chore(release): v3.0.0-beta.90 [skip ci] 2024-08-21 22:58:28 -04:00
Elliot DeNolf
3e5c31a024 chore(scripts): add db-vercel-postgres to publish list 2024-08-21 22:55:29 -04:00
Elliot DeNolf
631431e006 feat: @payloadcms/db-vercel-postgres adapter (#7806)
Dedicated adapter for Vercel Postgres

- Uses the `@vercel/postgres` package under the hood.
- No `pg` dependency, speeds up invocation
- Includes refactoring all base postgres functionality into a
`BasePostgresAdapter` type, which will ease implementation of [other
adapters supported by
drizzle-orm](https://orm.drizzle.team/docs/get-started-postgresql)

## Usage

```ts
import { buildConfig } from 'payload'
import { vercelPostgresAdapter } from '@payloadcms/db-vercel-postgres'

export default buildConfig({
  db: vercelPostgresAdapter({
    pool: {
      connectionString: process.env.DATABASE_URI,
    },
  }),
  // ...rest of config
})
```

### Automatic Connection String Detection

Have Vercel automatically detect from environment variable (typically
`process.env.POSTGRES_URL`)

```ts
export default buildConfig({
  db: postgresAdapter(),
  // ...rest of config
})
```
2024-08-21 22:54:47 -04:00
Paul
492d920133 fix(ui): upload has many no rows error (#7804) 2024-08-21 22:52:20 -04:00
Elliot DeNolf
f754edc375 chore(release): v3.0.0-beta.89 [skip ci] 2024-08-21 20:54:18 -04:00
Paul
d2571e10d6 feat: upload hasmany (#7796)
Supports `hasMany` upload fields, similar to how `hasMany` works in
other fields, i.e.:

```ts
{
  type: 'upload',
  relationTo: 'media',
  hasMany: true
}
```

---------

Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
Co-authored-by: James <james@trbl.design>
2024-08-21 20:44:04 -04:00
Alessio Gravili
a687cb9c5b Merge PR: Lexical migration and validation improvements 2024-08-21 18:31:53 -04:00
Alessio Gravili
cf6634111f fix(richtext-lexical): ensure errors during slate => lexical migration are caught and do not halt migration progress 2024-08-21 17:52:45 -04:00
Jarrod Flesch
1ee19d3016 feat: bulk upload (#7800)
## Description

Adds bulk upload functionality to upload enabled configs.

You can disable the ability by defining `upload.bulkUpload: false` in
your upload enabled config.

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] New feature (non-breaking change which adds functionality)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-21 17:44:34 -04:00
Alessio Gravili
9beaa281dc feat: log document id in ValidationError cause, if present 2024-08-21 17:31:31 -04:00
Alessio Gravili
5174c7092f fix(richtext-lexical): inaccurate detection of whether the editor is empty or not 2024-08-21 17:26:02 -04:00
Alessio Gravili
d894ac75f0 fix(richtext-lexical): migrate scripts not working due to migration hooks running during migrate script 2024-08-21 16:43:56 -04:00
Alessio Gravili
af0105ced5 fix: no longer handle disabling node deprecation warnings within bin script shebangs, as it errored on some systems (#7797)
Fixes https://github.com/payloadcms/payload/issues/7741

I have no idea why it broke and was not able to reproduce this at all.
But given the amount of people reporting this issue, it's not worth
keeping this around for the small benefit this brings
2024-08-21 17:01:57 +00:00
Tylan Davis
93e81314df fix(ui, richtext-lexical): corrects clickable areas on block headers (#7791)
## Description

Fixes an issue where Block component section titles were taking up the
entire clickable area of block headers.

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

<!-- Please delete options that are not relevant. -->

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-21 10:45:05 -04:00
Jarrod Flesch
163d1c85da chore: corrects icon color styles (#7792) 2024-08-21 10:28:01 -04:00
Jacob Fletcher
cb9b80aaf9 fix!: handles custom collection description components (#7789)
## Description

Closes #7784 by properly handling custom collection description
components via `admin.components.Description`. This component was
incorrectly added to the `admin.components.edit` key, and also was never
handled on the front-end. This was especially misleading because the
client-side config had a duplicative key in the proper position.

## Breaking Changes

This PR is only labeled as a breaking change because the key has changed
position within the config. If you were previously defining a custom
description component on a collection, simply move it into the correct
position:

Old:
```ts
{
  admin: {
    components: {
      edit: {
        Description: ''
      }
    }
  }
}
```

New:

```ts
{
  admin: {
    components: {
      Description: ''
    }
  }
}
```

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)
- [x] This change requires a documentation update

## Checklist:

- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [x] I have made corresponding changes to the documentation
2024-08-21 10:20:22 -04:00
Jarrod Flesch
cad1906725 feat: extends Button and extracts ListHeader components (#7777) 2024-08-21 09:37:11 -04:00
Elliot DeNolf
988c8848e9 chore(release): v3.0.0-beta.88 [skip ci] 2024-08-20 16:41:10 -04:00
Elliot DeNolf
95a8bb0d27 feat(ui): export Banner component (#7779)
Export `Banner` component
2024-08-20 20:07:03 +00:00
Paul
9c2ccbf61a fix(ui): on Table component crashing when looking for className on admin (#7776) 2024-08-20 19:03:18 +00:00
Paul
3ee0e842a5 fix(plugin-search): not being able to override labels (#7775)
Close https://github.com/payloadcms/payload/issues/7771
2024-08-20 18:54:30 +00:00
Tylan Davis
6ec982022e fix(ui): text clipping on document header title with Segoe UI font (#7774)
## Description

Fixes text clipping that occurs on the document header title when Segoe
UI font is used in the admin panel.

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

<!-- Please delete options that are not relevant. -->

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-20 17:35:06 +00:00
Elliot DeNolf
4f71df79fc ci: update codeowners file 2024-08-20 09:51:59 -04:00
Elliot DeNolf
227d2e0502 chore(release): v3.0.0-beta.87 [skip ci] 2024-08-20 09:10:00 -04:00
Jacob Fletcher
3a91deb0a4 feat: threads field config through components and strictly types props (#7754)
## Description

Threads the field config to all "field subcomponents" through props,
i.e. field label, description, error, etc. This way, the field config
that controls any particular component is easily accessible and strongly
typed, i.e. `props.field.maxLength`. This is true for both server and
client components, whose server-side props are now also contextually
typed. This behavior was temporarily removed in #7474 due to bloating
HTML, but has since been resolved in #7620. This PR also makes
significant improvements to component types by exporting explicit types
for _every component of every field_, each with its own client/server
variation. Now, a custom component can look something like this:

```tsx
import type { TextFieldLabelServerComponent } from 'payload'

import React from 'react'

export const CustomLabel: TextFieldLabelServerComponent = (props) => {
  return (
    <div>{`The max length of this field is: ${props?.field?.maxLength}`}</div>
  )
}
```

The following types are now available:

```ts
import type {
  TextFieldClientComponent,
  TextFieldServerComponent,
  TextFieldLabelClientComponent,
  TextFieldLabelServerComponent,
  TextFieldDescriptionClientComponent,
  TextFieldDescriptionServerComponent,
  TextFieldErrorClientComponent,
  TextFieldErrorServerComponent,
  // ...and so one for each field
} from 'payload'
```

BREAKING CHANGES:

In order to strictly type these components, a few breaking changes have
been made _solely to type definitions_. This only effects you if you are
heavily using custom components.

Old
```ts
import type { ErrorComponent, LabelComponent, DescriptionComponent } from 'payload'
```

New:
```ts
import type {
  FieldErrorClientComponent,
  FieldErrorServerComponent,
  FieldLabelClientComponent,
  FieldLabelServerComponent,
  FieldDescriptionClientComponent,
  FieldDescriptionServerComponent,
  // Note: these are the generic, underlying types of the more stricter types described above ^
  // For example, you should use the type that is explicit for your particular field and environment
  // i.e. `TextFieldLabelClientComponent` and not simply `FieldLabelClientComponent`
} from 'payload'
```

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
2024-08-20 04:25:10 +00:00
Jacob Fletcher
9e6e8357b8 docs: admin metadata (#7767) 2024-08-19 23:07:10 -04:00
Elliot DeNolf
0dd17e6347 chore(release): v3.0.0-beta.86 [skip ci] 2024-08-19 21:27:26 -04:00
James Mikrut
17312d9f90 Fix/postgres migrate args (#7766)
## Description

Replaces the export of `MigrateUpArgs` and `MigrateDownArgs` from
`db-postgres`
2024-08-20 01:00:13 +00:00
Paul
0c36cbde73 fix: type generation for block fields with no blocks (#7765) 2024-08-19 22:34:19 +00:00
Alessio Gravili
ebd43c7763 feat: pre-compile ui and richtext-lexical with react compiler (#7688)
This noticeably improves performance in the admin panel, for example
when there are multiple richtext editors on one page (& likely
performance in other areas too, though I mainly tested rich text).

The babel plugin currently only optimizes files with a 'use client'
directive at the top - thus we have to make sure to add use client
wherever possible, even if it's imported by a parent client component.

There's one single component that broke when it was compiled using the
React compiler (it stopped being reactive and failed one of our admin
e2e tests):
150808f608
opting out of it completely fixed that issue

Fixes https://github.com/payloadcms/payload/issues/7366
2024-08-19 17:31:36 -04:00
Jarrod Flesch
adf2f31178 fix: useField incorrect initialization of errorMessage on update (#7756) 2024-08-19 17:00:39 -04:00
Elliot DeNolf
beadc0158e chore(release): v3.0.0-beta.85 [skip ci] 2024-08-19 16:41:30 -04:00
Dan Ribbens
bb09da08c2 fix: migrate error on windows (#7759)
handle windows compatible file names when reading migrations

---------

Co-authored-by: Alessio Gravili <alessio@gravili.de>
2024-08-19 15:46:40 -04:00
Paul
ab09f2aff5 fix(ui): tabs preferences not being saved (#7761) 2024-08-19 19:25:31 +00:00
Alessio Gravili
2f3829083d fix(richtext-lexical): richtext editor features overriding other editor features props if multiple editors in one document (#7758)
Example: richText editor 1 and 2 both have UploadFeature. richText
editor 1 calls UploadFeature() with custom fields, richText editor 2
calls UploadFeature() with NO custom fields. Before this PR, richText
editor 1 would not have had any custom fields, as richText editor 2 will
override the feature object (specifically its props).
2024-08-19 12:01:31 -04:00
Jacob Fletcher
a526c7becd feat: custom view and document-level metadata (#7716) 2024-08-18 23:22:38 -04:00
Elliot DeNolf
2835e1d709 feat: abstract postgres base adapter (#7732)
Abstracts Postgres base adapter in order to allow future postgres-based
adapters.
2024-08-16 18:51:39 -04:00
Alessio Gravili
4808e31276 chore: fix dev:postgres command, disable dependency checker in core dev (#7733) 2024-08-16 19:46:49 +00:00
Elliot DeNolf
bd51fd1390 chore: re-enable husky pre-commit 2024-08-16 15:22:56 -04:00
Tylan Davis
b3b1cd2c23 fix: prevent vertical scrolling on tab fields (#7729)
## Description

Prevents tabs fields from displaying vertical scrollbars in certain
cases with different viewports/zoom levels.

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

<!-- Please delete options that are not relevant. -->

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-16 15:13:12 -04:00
Alessio Gravili
d67f674160 chore: update all templates (#7731)
Old blank templates had invalid pregenerated importMap. Would error for
fresh apps from create-payload-app. And website was on an old version
riddled with bugs
2024-08-16 18:59:58 +00:00
Alessio Gravili
6eb4438dc8 fix(ui): relationship cells in table from list drawer not shown (#7730)
Also a nice performance improvement. The list drawer was previously
fetching data with depth 1. This will cause the relationship cell to
break, as it expects the relationship data to be a string/number, not a
populated object with the id inside.

Now, it fetches using depth 0 - same as the normal list view
2024-08-16 18:44:59 +00:00
Elliot DeNolf
2d6e7f8a37 chore(release): v3.0.0-beta.84 [skip ci] 2024-08-16 13:56:50 -04:00
James Mikrut
3d37d74c6e fix: adds default drizzle package exports (#7728)
Default exports were missing for Drizzle package.
2024-08-16 13:40:41 -04:00
James Mikrut
de19822ed4 fix: ensures user is accurate in useAuth (#7727)
## Description

Fixes an issue where the `user` could be out of date after logging in.
2024-08-16 17:10:32 +00:00
Tylan Davis
2b2bcb5264 fix: corrects logout icon styling (#7726)
## Description

before: 
<img width="89" alt="Screenshot 2024-08-16 at 12 43 56 PM"
src="https://github.com/user-attachments/assets/1052cfdb-6dde-4b65-a4c0-e37a909dac34">

after:
<img width="48" alt="Screenshot 2024-08-16 at 12 43 35 PM"
src="https://github.com/user-attachments/assets/aa4d6aed-4a78-4b17-a209-df3618b273a1">

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

<!-- Please delete options that are not relevant. -->

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-16 17:01:42 +00:00
Elliot DeNolf
e9b01e6d9f chore(release): v3.0.0-beta.83 [skip ci] 2024-08-16 12:36:30 -04:00
Alessio Gravili
b0a760193e fix: type RelationshipFieldClient typed incorrectly (#7725) 2024-08-16 12:35:05 -04:00
Jarrod Flesch
95569e44e4 fix: login with username server validations (#7719) 2024-08-16 12:07:53 -04:00
Paul
11816080a6 fix: bin script error when running on linux (#7721)
Fixes https://github.com/payloadcms/payload/issues/7717
2024-08-16 10:07:03 -06:00
Paul
3a86822f0a fix(ui): ensure that aborting Autosave always has a valid reason for the controller - fixes uncaught error (#7723) 2024-08-16 16:04:32 +00:00
Jarrod Flesch
6f8604e18c fix: ensures users cannot be created without confirming pw (#7583) 2024-08-16 11:44:27 -04:00
Tylan Davis
aec3f5e308 chore: admin panel style updates (#7720)
## Description

Minor admin panel style updates:
- Adjusts document header title spacing.
- Makes toast notifications more apparent.
- Adjusts alignment of create new button.
- Improves chevron icon.

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

<!-- Please delete options that are not relevant. -->

- [x] Chore (non-breaking change which does not add functionality)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-16 15:23:08 +00:00
Jarrod Flesch
e0a5de6730 chore: extends dropzone and upload field (#7713)
## Description

Tweaks to Upload and Dropzone components, making them more extendable.

- Dropzone adds prop to allow multiple files
- Upload correctly sets url if state is initialized with a File

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Chore (non-breaking change which does not add functionality)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-16 09:38:41 -04:00
Paul
5eee49da9a feat(plugin-seo): pass req through to generate functions (#7711)
Closes https://github.com/payloadcms/payload/issues/7708
2024-08-15 23:09:08 +00:00
dependabot[bot]
b7d01dec70 chore(deps): bump pnpm/action-setup from 3 to 4 in /.github/actions/setup in the github_actions group across 1 directory (#7687)
Bumps the github_actions group with 1 update in the
/.github/actions/setup directory:
[pnpm/action-setup](https://github.com/pnpm/action-setup).

Updates `pnpm/action-setup` from 3 to 4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pnpm/action-setup/releases">pnpm/action-setup's
releases</a>.</em></p>
<blockquote>
<h2>v4.0.0</h2>
<p>An error is thrown if one version of pnpm is specified in the
<code>packageManager</code> field of <code>package.json</code> and a
different version is specified in the action's settings <a
href="https://redirect.github.com/pnpm/action-setup/pull/122">#122</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fe02b34f77"><code>fe02b34</code></a>
docs: bump action-setup version in README</li>
<li><a
href="bee1f099e5"><code>bee1f09</code></a>
feat: throw error when multiple versions specified (<a
href="https://redirect.github.com/pnpm/action-setup/issues/122">#122</a>)</li>
<li><a
href="ce859e384f"><code>ce859e3</code></a>
refactor: replace <code>fs-extra</code> with Node.js built-in fs methods
(<a
href="https://redirect.github.com/pnpm/action-setup/issues/120">#120</a>)</li>
<li><a
href="2ab6dce4f5"><code>2ab6dce</code></a>
docs(README): fix link to LICENSE</li>
<li><a
href="e280758d01"><code>e280758</code></a>
docs(README): update dependency versions (<a
href="https://redirect.github.com/pnpm/action-setup/issues/117">#117</a>)</li>
<li><a
href="129abb77bf"><code>129abb7</code></a>
Bump undici from 5.28.2 to 5.28.3 (<a
href="https://redirect.github.com/pnpm/action-setup/issues/115">#115</a>)</li>
<li>See full diff in <a
href="https://github.com/pnpm/action-setup/compare/v3...v4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pnpm/action-setup&package-manager=github_actions&previous-version=3&new-version=4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-15 15:57:33 -04:00
Elliot DeNolf
0618130fe3 chore(release): v3.0.0-beta.82 [skip ci] 2024-08-15 15:46:12 -04:00
Jacob Fletcher
cd245793fc chore(ui): resolves self-referencing imports (#7707) 2024-08-15 14:27:19 -04:00
Dan Ribbens
3a6c75a1a3 fix: importMap windows paths (#7706)
Fix windows compatibility for importMap generation
2024-08-15 17:57:48 +00:00
Alessio Gravili
5a683b6947 chore: fix issues running postgres in our dev test suites (#7704) 2024-08-15 16:58:00 +00:00
Elliot DeNolf
9b27f03e61 feat(eslint): no-imports-from-self rule (#7691)
New rule to prevent a package from importing from itself.
2024-08-15 09:02:29 -04:00
Elliot DeNolf
89746ebe09 chore(eslint): update relative import regex to handle more scenarios (#7690)
Updates no-relative-monorepo-import regex to handle more scenarios:

 Scenarios that will violate the rule:
```ts
import { something } from '../../payload/src/utilities/some-util.js'
import { something } from '../../../packages/payload/src/utilities/some-util.js'
import { something } from 'packages/payload/src/utilities/some-util.js'
```
2024-08-14 23:57:22 -04:00
dependabot[bot]
eacf2030cd chore(deps): bump the github_actions group with 2 updates (#7686)
Bumps the github_actions group with 2 updates:
[pnpm/action-setup](https://github.com/pnpm/action-setup) and
[supercharge/mongodb-github-action](https://github.com/supercharge/mongodb-github-action).

Updates `pnpm/action-setup` from 3 to 4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pnpm/action-setup/releases">pnpm/action-setup's
releases</a>.</em></p>
<blockquote>
<h2>v4.0.0</h2>
<p>An error is thrown if one version of pnpm is specified in the
<code>packageManager</code> field of <code>package.json</code> and a
different version is specified in the action's settings <a
href="https://redirect.github.com/pnpm/action-setup/pull/122">#122</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fe02b34f77"><code>fe02b34</code></a>
docs: bump action-setup version in README</li>
<li><a
href="bee1f099e5"><code>bee1f09</code></a>
feat: throw error when multiple versions specified (<a
href="https://redirect.github.com/pnpm/action-setup/issues/122">#122</a>)</li>
<li><a
href="ce859e384f"><code>ce859e3</code></a>
refactor: replace <code>fs-extra</code> with Node.js built-in fs methods
(<a
href="https://redirect.github.com/pnpm/action-setup/issues/120">#120</a>)</li>
<li><a
href="2ab6dce4f5"><code>2ab6dce</code></a>
docs(README): fix link to LICENSE</li>
<li><a
href="e280758d01"><code>e280758</code></a>
docs(README): update dependency versions (<a
href="https://redirect.github.com/pnpm/action-setup/issues/117">#117</a>)</li>
<li><a
href="129abb77bf"><code>129abb7</code></a>
Bump undici from 5.28.2 to 5.28.3 (<a
href="https://redirect.github.com/pnpm/action-setup/issues/115">#115</a>)</li>
<li>See full diff in <a
href="https://github.com/pnpm/action-setup/compare/v3...v4">compare
view</a></li>
</ul>
</details>
<br />

Updates `supercharge/mongodb-github-action` from 1.10.0 to 1.11.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/supercharge/mongodb-github-action/releases">supercharge/mongodb-github-action's
releases</a>.</em></p>
<blockquote>
<p>Release 1.11.0</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/supercharge/mongodb-github-action/blob/main/CHANGELOG.md">supercharge/mongodb-github-action's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/superchargejs/mongodb-github-action/compare/v1.10.0...v1.11.0">1.11.0</a>
- 2024-05-22</h2>
<h3>Added</h3>
<ul>
<li>added <code>mongodb-container-name</code> input: this option allows
you to define the Docker container name</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>use the <code>mongo</code> command to interact with MongoDB versions
4.x or lower. Previously, we only checked for MongoDB 4 and would use
<code>mongosh</code> for MongoDB 3 (and lower). <a
href="https://redirect.github.com/supercharge/mongodb-github-action/pull/61">Thanks
to Aravind!</a></li>
</ul>
<h3>Updated</h3>
<ul>
<li>bump dependencies</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5a87bd81f8"><code>5a87bd8</code></a>
prepare changelog for 1.11.0</li>
<li><a
href="7c12fc679c"><code>7c12fc6</code></a>
update readme</li>
<li><a
href="ad73029553"><code>ad73029</code></a>
bump mongoose dependency</li>
<li><a
href="268fb2c93c"><code>268fb2c</code></a>
Merge pull request <a
href="https://redirect.github.com/supercharge/mongodb-github-action/issues/61">#61</a>
from aravindnc/main</li>
<li><a
href="12b898a9c8"><code>12b898a</code></a>
Fix to use mongo client if MongoDB verison is less than or equal to
4.</li>
<li><a
href="b8277548e0"><code>b827754</code></a>
wait 20 seconds</li>
<li><a
href="5f37c5fb42"><code>5f37c5f</code></a>
revert ESLint to 8.x</li>
<li><a
href="fcc7443a6b"><code>fcc7443</code></a>
bump verions</li>
<li><a
href="fde299bc70"><code>fde299b</code></a>
bump deps</li>
<li><a
href="9ceda80ede"><code>9ceda80</code></a>
bump versions of GitHub Actions</li>
<li>Additional commits viewable in <a
href="https://github.com/supercharge/mongodb-github-action/compare/1.10.0...1.11.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-14 21:56:24 -04:00
Elliot DeNolf
86428539f5 chore: add packageManager property for dependabot 2024-08-14 21:30:53 -04:00
Elliot DeNolf
a7f519c53a chore(release): v3.0.0-beta.81 [skip ci] 2024-08-14 19:53:07 -04:00
Alessio Gravili
49a2d70fbb feat: allow passing false as PayloadComponent which signals that the component should not be rendered (#7682)
If it's undefined/null => Fallback Component may be rendered
If it's false => No component should be rendered - as if an empty
component was passed in

This ensures that the user does not have to install `@payloadcms/ui`
anymore, which previously exported an empty component to be used in
component paths
2024-08-14 22:31:58 +00:00
Alessio Gravili
cb7fa00a6f fix: use tsx instead of swc as default bin script transpiler, as swc errors when it encounters 'next/cache' (#7681)
Fixes https://github.com/payloadcms/payload/issues/7677

- Payload bin scripts were not properly working on windows
- Use tsx by default instead of swc, as swc does not handle next/cache
imports without the .js at the end
- Support other node runtimes through --disable-transpile flag
2024-08-14 16:40:31 -04:00
Jacob Fletcher
a212cdef3f fix(next): supports root document view overrides as separate from default edit view (#7673)
## Description

We've since lost the ability to override the document view at the
root-level. This was a feature that made it possible to override _the
entire document routing/view structure_, including the document
header/tabs and all nested routes within, i.e. the API route/view, the
Live Preview route/view, etc. This is distinct from the "default" edit
view, which _only_ targets the component rendered within the "edit" tab.
This regression was introduced when types were simplified down to better
support "component paths" here: #7620. The `default` key was incorrectly
used as the "root" view override. To continue to support stricter types
_and_ root view overrides, a new `root` key has been added to the
`views` config.

You were previously able to do this:

```tsx
import { MyComponent } from './MyComponent.js'

export const MyCollection = {
  // ...
  admin: {
    views: {
      Edit: MyComponent
    }
  }
}
```

This is now done like this:

```tsx
export const MyCollection = {
  // ...
  admin: {
    views: {
      edit: {
        root: {
          Component: './path-to-my-component.js'
        }
      }
    }
  }
}
```

Some of the documentation was also incorrect according to the new
component paths API.

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)
- [x] This change requires a documentation update

## Checklist:

- [x] Existing test suite passes locally with my changes
- [x] I have made corresponding changes to the documentation
2024-08-14 16:02:14 -04:00
Paul
4f323a3754 fix(ui): issue with checking for undefined json when autosave and validate is enabled (#7678) 2024-08-14 18:47:27 +00:00
Paul
f5e7578b41 chore: add command to run inside the importMap error (#7674) 2024-08-14 17:39:12 +00:00
Elliot DeNolf
0bf27b117a chore(release): v3.0.0-beta.80 [skip ci] 2024-08-14 13:14:57 -04:00
Patrik
806c22e6bd fix(next): properly closes leave-without-saving modal after navigating from Leave anyway button (#7661) 2024-08-14 13:05:26 -04:00
Alessio Gravili
39d7b717a9 fix: sidebar nav jumping around when loading page (#7574)
Fixes this:


https://github.com/user-attachments/assets/1c637bca-0c13-43f6-bcd7-6ca58da9ae77
2024-08-14 16:23:57 +00:00
Paul
9d1997e6a0 chore: update docs for redirects plugin for new redirect type feature (#7672) 2024-08-14 16:22:11 +00:00
Alessio Gravili
c65f5027d6 fix(ui): ensure field components safely access field.admin property (#7670) 2024-08-14 12:06:01 -04:00
Elliot DeNolf
dc496e4387 chore(release): v3.0.0-beta.79 [skip ci] 2024-08-14 09:21:24 -04:00
Alessio Gravili
3d86bf1974 chore: update website and blank templates to incorporate import map changes (#7664) 2024-08-14 09:10:40 -04:00
Alessio Gravili
96e7c95ebc chore: upgrade to pnpm v9, regenerate lockfile (#7369)
- regenerates the lockfile
- upgrades pnpm from v8 to v9.7.0 minimum
- ensures playwright does not import payload config. Even after our
importmap revamp that made the payload config server-only / node-safe, I
was getting these `Error: Invariant: AsyncLocalStorage accessed in
runtime where it is not available` errors in combination with pnpm v9
and lockfile regeneration.
This does not happen with pnpm v8, however I'm still blaming playwright
for this, as this does not happen in dev and we've had this specific
error with playwright in the past when we were importing the payload
config. Perhaps it's related to both playwright and the future Next.js
process importing the same config file, and not related to the config
file containing client-side React code.
Making sure playwright doesn't import the config fixed it (it was
importing it through the import map generation). The import map
generation is now run in a separate process, and playwright simply waits
for it
- One positive thing: this pr fixes a bunch of typescript errors with
react-select components. We got those errors because react-select types
are not compatible with react 19. lockfile regeneration fixed that (not
related to pnpm v9) - probably because we were installing mismatching
react versions (I saw both `fb9a90fa48-20240614` and `06d0b89e-20240801`
in our lockfile). I have thus removed the caret for react and react-dom
in our package.json - now it's consistent
2024-08-14 08:57:04 -04:00
Alessio Gravili
fca4ee995e fix(richtext-lexical): inline blocks and tables not functioning correctly if they are used in more than one editor on the same page (#7665)
Fixes https://github.com/payloadcms/payload/issues/7579

The problem was that multiple richtext editors shared the same drawer
slugs for the table and inline block drawers.
2024-08-13 21:46:23 -04:00
Elliot DeNolf
352ed0ebef ci: debug github.ref condition 2024-08-13 20:00:29 -04:00
Elliot DeNolf
bcf9b17321 ci: test github.ref 2024-08-13 19:40:37 -04:00
Alessio Gravili
a19263245f feat(richtext-lexical)!: move migration related features to /migrate subpath export in order to decrease module count when those are not used (#7660)
This lowers the module count by 31 modules

BREAKING: Migration-related lexical modules are now exported from
`@payloadcms/richtext-lexical/migrate` instead of
`@payloadcms/richtext-lexical`
2024-08-13 20:20:05 +00:00
Alessio Gravili
78e55d61be docs: move import map section from admin/overview to admin/components (#7659) 2024-08-13 19:17:14 +00:00
Alessio Gravili
cea272e189 docs: update ui field docs to use component paths (#7658) 2024-08-13 14:39:03 -04:00
Alessio Gravili
8b13dc64d1 docs: update docs with component path / client config changes (#7657) 2024-08-13 14:34:42 -04:00
Elliot DeNolf
5fc9f76406 feat: filename compound index (#7651)
Allow a compound index to be used for upload collections via a
`filenameCompoundIndex` field. Previously, `filename` was always treated
as unique.

Usage:

```ts
{
  slug: 'upload-field',
   upload: {
     // Slugs to include in compound index
     filenameCompoundIndex: ['filename', 'alt'],
  },
}
```
2024-08-13 13:55:10 -04:00
Alessio Gravili
6c0f99082b chore: install tsx in monorepo (#7656)
CI depends on it, and swc does not support the `p-limit` dependency used
in CI scripts
2024-08-13 17:32:46 +00:00
Alessio Gravili
90b7b20699 feat!: beta-next (#7620)
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:**
![CleanShot 2024-07-29 at 22 49
12@2x](https://github.com/user-attachments/assets/4428e766-b368-4bcf-8c18-d0187ab64f3e)

**dev /admin after:**
![CleanShot 2024-07-29 at 22 50
49@2x](https://github.com/user-attachments/assets/f494c848-7247-4b02-a650-a3fab4000de6)

---

**dev /test before:**
![CleanShot 2024-07-29 at 22 56
18@2x](https://github.com/user-attachments/assets/1a7e9500-b859-4761-bf63-abbcdac6f8d6)

**dev /test after:**
![CleanShot 2024-07-29 at 22 47
45@2x](https://github.com/user-attachments/assets/f89aa76d-f2d5-4572-9753-2267f034a45a)

---

**build before:**
![CleanShot 2024-07-29 at 22 57
14@2x](https://github.com/user-attachments/assets/5f8f7281-2a4a-40a5-a788-c30ddcdd51b5)

**build after::**
![CleanShot 2024-07-29 at 22 56
39@2x](https://github.com/user-attachments/assets/ea8772fd-512f-4db0-9a81-4b014715a1b7)

### 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.

![CleanShot 2024-07-29 at 23 07
07@2x](https://github.com/user-attachments/assets/1e75aa4c-7a4c-419f-9070-216bb7b9a5e5)

![CleanShot 2024-07-29 at 23 09
40@2x](https://github.com/user-attachments/assets/b4c96450-6b7e-496c-a4f7-59126bfd0991)

- [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>
2024-08-13 12:54:33 -04:00
Patrik
9cb84c48b9 fix(live-preview): encode query string url (#7635)
## Description

Fixes #7529 

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
2024-08-13 10:24:30 -04:00
Elliot DeNolf
390f88867f chore(release): v3.0.0-beta.78 [skip ci] 2024-08-13 09:21:05 -04:00
James Mikrut
b33b5f43f4 fix: #7580 config deepmerge (#7639)
## Description

https://github.com/payloadcms/payload/issues/7580 - Fixes an infinite
loop caused by a faulty deepMerge in config sanitization.
2024-08-12 16:50:21 -04:00
Paul
56aded8507 feat: add support for custom image size file names (#7634)
Add support for custom file names in images sizes

```ts
{
  name: 'thumbnail',
  width: 400,
  height: 300,
  generateImageName: ({ height, sizeName, extension, width }) => {
    return `custom-${sizeName}-${height}-${width}.${extension}`
  },
}
```
2024-08-12 12:25:20 -06:00
Paul
78dd6a2d5b feat(plugin-form-builder): pass beforeChange params into beforeEmail hook and add types to it (#7626)
Form Builder Plugin BeforeEmail hook now takes a generic for your
generated types and it has the full hook params available to it.

```ts
import type { BeforeEmail } from '@payloadcms/plugin-form-builder'
// Your generated FormSubmission type
import type {FormSubmission} from '@payload-types'

// Pass it through and 'data' or 'originalDoc' will now be typed
const beforeEmail: BeforeEmail<FormSubmission> = (emailsToSend, beforeChangeParams) => {
  // modify the emails in any way before they are sent
  return emails.map((email) => ({
    ...email,
    html: email.html, // transform the html in any way you'd like (maybe wrap it in an html template?)
  }))
}
```
2024-08-12 12:22:52 -06:00
Alessio Gravili
a063b81460 fix: autoLogin not working if old, invalid token is present (#7456) 2024-08-12 12:41:45 -04:00
James Mikrut
18d9314f22 docs: adds prod migrations (#7631)
## Description

Adds docs for executing migrations in production.
2024-08-12 11:45:39 -04:00
Patrik
8d120373a7 fix(payload): filtering by polymorphic relationships with drafts enabled (#7570)
## Description

V2 PR [here](https://github.com/payloadcms/payload/pull/7565)

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
2024-08-12 10:34:21 -04:00
Patrik
f88cef5470 fix(ui): render singular label for ArrayCell when length is 1 (#7586)
## Description

V2 PR [here](https://github.com/payloadcms/payload/pull/7585)

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] Existing test suite passes locally with my changes
2024-08-12 10:33:28 -04:00
Paul
5dfcffa281 feat(plugin-redirects): added new option for redirect type in the redirects collection (#7625)
You can now add a redirect type to your redirects if needed:

```ts
// Supported types
redirectTypes: ['301', '302'],

// Override the select field
redirectTypeFieldOverride: {
  label: 'Redirect Type (Overridden)',
},
```
2024-08-11 13:18:49 -06:00
Elliot DeNolf
fa3d250053 feat: indent migration sql (#7475)
Properly indent migration sql
2024-08-09 22:41:28 -04:00
Paul
4b2a9f75d0 fix(ui): field permissions not being correctly updated when locale changes (#7611)
Closes https://github.com/payloadcms/payload/issues/7262
2024-08-09 18:39:14 -06:00
Dan Ribbens
e225783d76 chore(db-sqlite): readme header (#7609) 2024-08-09 16:45:33 -04:00
Tylan Davis
0d552fd523 chore: adjusts admin UI styling (#7557)
## Description

- Improves mobile styling of Payload admin UI.
- Reduces font size on dashboard cards.
- Improves the block/collapsible/array field styling.

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

<!-- Please delete options that are not relevant. -->

- [x] Chore (non-breaking change which does not add functionality)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-09 11:19:36 -04:00
Paul
69ada97df5 fix(ui): apiKey field not being customisable and field access control not being updated with correct data (#7591)
You can now override the apiKey field with access control by adding this
field to your auth collection:

```ts
{
  name: 'apiKey',
  type: 'text',
  access: {
    update: ({ req }) => req.user.role === 'admin',
  }
}
```

Translated labels are now also supported.

Note that `siblingData` isn't working still in FieldAccess control and
`data` only works in non-dynamic fields, eg. fields not in an array or
block for now.
2024-08-09 08:55:17 -06:00
Paul
81e7355ee0 fix: set correct step nav path to Account on account page (#7599) 2024-08-09 00:56:11 +00:00
Paul
ce8b95f6bb fix: add editDepth to account view so that it doesn't redirect from modals (#7597)
Closes https://github.com/payloadcms/payload/issues/7593
2024-08-09 00:32:46 +00:00
James Mikrut
c1b0d93c93 feat: adds classnames to list, edit views (#7596)
## Description

Copy of #7595 for beta branch
2024-08-08 20:05:07 -04:00
Jarrod Flesch
6227276d2c fix: corrects local strategy user lookup when using loginWithUsername (#7587)
## Description

Fixes the local strategy user lookup.

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] I have added tests that prove my fix is effective or that my
feature works
- [ ] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-08 19:51:12 -04:00
Elliot DeNolf
ee62ed6ebb chore(release): v3.0.0-beta.77 [skip ci] 2024-08-08 17:13:02 -04:00
Elliot DeNolf
0283039257 chore(db-*): remove unneeded drizzle import (#7590)
Removes unused drizzle snapshot
2024-08-08 17:11:34 -04:00
Jessica Chowdhury
b546c7b655 fix: empty path in error message (#7555)
## Description

Closes #7524

The query path is overwritten as an empty string in the
`getLocalizedPaths()` function - then when it should throw an invalid
path error it no longer has this info.

- [X] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [ ] Chore (non-breaking change which does not add functionality)
- [X] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] Change to the
[templates](https://github.com/payloadcms/payload/tree/main/templates)
directory (does not affect core functionality)
- [ ] Change to the
[examples](https://github.com/payloadcms/payload/tree/main/examples)
directory (does not affect core functionality)
- [ ] This change requires a documentation update

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [X] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-08 10:29:03 +00:00
Elliot DeNolf
a933eb7311 chore(release): v3.0.0-beta.76 [skip ci] 2024-08-07 15:18:17 -04:00
Elliot DeNolf
b5d65dd1ac fix(richtext-lexical): next.js multiple refs of same fix (#7572)
Fixes some issue w/ Next.js and passing the same ref multiple times.
2024-08-07 15:17:33 -04:00
Elliot DeNolf
c4ee623907 chore(release): v3.0.0-beta.75 [skip ci] 2024-08-07 14:01:09 -04:00
James Mikrut
1cb1e5e8b3 feat(db-*): allows for running migrations in production automatically (#7563)
## Description

Introduces a pattern for running migrations upon Payload init in
production.
2024-08-07 13:57:12 -04:00
Paul
e0699838e1 chore(ui): update useField jsdoc comment to point to the right internal hook (#7568) 2024-08-07 17:49:32 +00:00
Dan Ribbens
46f70d9df4 fix(db-postgres): #7492 migrate snapshots (#7540)
## Description

Fixes #7492 

In order to run createMigration, we need to read in the previous
snapshot file if one exists. When that snapshot was generated from an
older version of drizzle-kit, we have to first migrate it up match the
latest version for drizzle to generate the new migration. This change
adds in the call to check the version and migrate the snapshot if
needed.
2024-08-07 13:49:08 -04:00
Paul
b7e2c59622 fix(plugin-seo): issue with generating image from a function (#7566) 2024-08-07 17:35:43 +00:00
Jarrod Flesch
0cc7184023 fix: hydrate permissions on dashboard, fix active menu item logic 2024-08-07 12:14:58 -04:00
Jarrod Flesch
e905675a05 chore!: adjusts auth hydration from server (#7545)
Fixes https://github.com/payloadcms/payload/issues/6823

Allows the server to initialize the AuthProvider via props. Renames
`HydrateClientUser` to `HydrateAuthProvider`. It now only hydrates the
permissions as the user can be set from props. Permissions can be
initialized from props, but still need to be hydrated for some pages as
access control can be specific to docs/lists etc.

**BREAKING CHANGE**
- Renames exported `HydrateClientUser` to `HydrateAuthProvider`
2024-08-07 11:10:53 -04:00
Paul
4a20a63563 fix(ui): fixes issue when filtering by checkbox value in a different language (#7547)
Fixes https://github.com/payloadcms/payload/issues/7447
2024-08-07 00:48:50 +00:00
Paul
8d1fc6e8fb feat!: bump next canary to 104 and update withPayload for new config (#7541)
We are now bumping up the Next canary version to `15.0.0-canary.104` and
`react` and `react-dom` to `^19.0.0-rc-06d0b89e-20240801`.

Your new dependencies should look like this:
```
"next": "15.0.0-canary.104",
"react": "^19.0.0-rc-06d0b89e-20240801",
"react-dom": "^19.0.0-rc-06d0b89e-20240801",
```

---------

Co-authored-by: Alessio Gravili <alessio@gravili.de>
2024-08-06 23:54:34 +00:00
Patrik
62744e79ac fix(next, payload): enable relationship & upload version tracking when localization enabled (#7508) 2024-08-06 12:28:06 -04:00
Jarrod Flesch
e8bed7b315 chore: call refresh after the subscription is ready, fixes CI (#7542)
LivePreview data was stale if the user entered data while the socket
connection was being established. This change ensures fresh data is
fetched after the connection is established.

This is easy to see when turning on 4G connection and in CI, where it is
especially slow.
2024-08-06 12:17:50 -04:00
Alessio Gravili
f2b8ddb299 Merge PR: fix lexical upload html converter, export missing nodes #7539
Fixes https://github.com/payloadcms/payload/issues/7495

When the Upload HTML Converter was called from the local API, the upload
document did not populate properly due to overrideAccess not being
passed through to the dataloader. This PR also adds new properties to
the afterRead field hook, so that these can be used in the lexical html
field.

Reproduction here:
https://github.com/payloadcms/payload/tree/chore/reproduce-html-converter-issue

**BREAKING:** If you define your own, custom lexical HTML Converters
that have sub-nodes, or if you directly call the
`convertLexicalNodesToHTML` function anywhere, you now need to pass
through the `showHiddenFields`, draft and `overrideAccess` props to the
`convertLexicalNodesToHTML` function. These are available in the
arguments of your HTML Converter function
2024-08-06 12:04:56 -04:00
Alessio Gravili
ffd8ea516d feat(richtext-lexical): export serialized inline blocks and table node types 2024-08-06 11:42:09 -04:00
Paul
3bf09703e9 chore: turn off autocomplete for create first user form (#7538)
Turns off autocomplete on the first user form so it doesn't conflict
with wrong credentials being autofilled
2024-08-06 15:34:26 +00:00
Alessio Gravili
c15d679b65 fix(richtext-lexical)!: html converters not respecting overrideAccess property when populating values, in local API 2024-08-06 11:15:47 -04:00
Jarrod Flesch
a422a0d568 fix: scopes preferences queries and mutations by user (#7534)
Fixes https://github.com/payloadcms/payload/issues/7530

Properly scopes preferences queries/mutations by user.
2024-08-06 10:35:46 -04:00
Jarrod Flesch
edaeb1e29f fix: ensure pw confirmation when creating users in admin panel (#7535) 2024-08-06 10:31:08 -04:00
Jessica Chowdhury
6f35c356fe fix: custom meta icons getting overwritten by default icon (#7466)
## Description

Issue reported by Trading Point.

Payload favicon is still shown even when a custom icon is provided.

To replicate add to Payload config:
```ts
  admin: {
    meta: {
      icons: [
        {
          url: '/images/test.jpg',
          fetchPriority: 'high',
          sizes: '16x16',
        },
      ],
    },
  },
```

- [X] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [X] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [X] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-06 14:01:46 +00:00
Elliot DeNolf
0b9397399a chore(release): v3.0.0-beta.74 [skip ci] 2024-08-06 09:38:20 -04:00
Jarrod Flesch
cdcc35ccdb chore: fixes build error stemming from LoginField (#7532) 2024-08-06 09:15:21 -04:00
Jarrod Flesch
442189ec48 fix: email and username fields rendering in drawers (#7520)
Fixes https://github.com/payloadcms/payload/issues/7428

Now email and username fields are rendered with the RenderFields
component, making them behave similarly to other fields. They now appear
and can respect doc permissions, readOnly settings, etc.
2024-08-05 20:18:32 -04:00
Alessio Gravili
5d1cc760c9 fix(richtext-lexical): various table and icon style issues (#7522) 2024-08-05 22:10:18 +00:00
Alessio Gravili
2f90683c7d Merge PR: upgrade lexical, add table feature converter (#7521)
This PR
- upgrades lexical and ports all bug fixes from the playground over
- adds table action buttons. When hovering the edges of the table,
buttons pop up to easily add a new table column or row
- adds an html converter for the table feature
- makes the placeholder shown in the editor when no text is present
accessible

**BREAKING:** This upgrades lexical from 0.16.1 to 0.17.0. If you have
any lexical packages installed in your project, please update them
accordingly. Additionally, if you depend on the lexical APIs, please
consult their changelog, as lexical may introduce breaking changes:
https://github.com/facebook/lexical/releases/tag/v0.17.0
2024-08-05 17:18:57 -04:00
Patrik
3f5403a52a fix(ui): prevents hasMany text going outside of input boundaries (#7455)
## Description

V2 PR [here](https://github.com/payloadcms/payload/pull/7454)

`Before`:
![Screenshot 2024-07-31 at 12 40
50 PM](https://github.com/user-attachments/assets/ce61f4fc-e676-4273-aa4c-72610cb459b3)

`After`:
![Screenshot 2024-07-31 at 12 40
23 PM](https://github.com/user-attachments/assets/d92631eb-28fb-46ca-bc23-46c7916bba34)

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] Existing test suite passes locally with my changes
2024-08-05 17:10:35 -04:00
Alessio Gravili
9bccdfd60a feat(richtext-lexical): add HTML converter to table feature 2024-08-05 17:01:21 -04:00
Patrik
62666a9897 fix(ui): properly handles ID field component type based on payload.db.defaultIDType (#7416)
## Description

Fixes #7354 

Since the `defaultIDType` for IDs in `postgres` are of type `number` -
the `contains` operator should be available in the filter options.

This PR checks the `defaultIDType` of ID and properly outputs the
correct component type for IDs

I.e if ID is of type `number` - the filter operators for ID should
correspond to the the operators of type number as well

The `contains` operator only belongs on fields of type string, aka of
component type `text`

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] Existing test suite passes locally with my changes
2024-08-05 16:39:27 -04:00
Alessio Gravili
eb27b84854 chore(richtext-lexical): backport various minor bugfixes from lexical playground 2024-08-05 16:35:13 -04:00
Alessio Gravili
c3480811d3 feat(richtext-lexical): accessible editor placeholders 2024-08-05 16:19:02 -04:00
Alessio Gravili
12ba820de4 feat(richtext-lexical): add table hover actions to quickly add rows or columns 2024-08-05 16:08:31 -04:00
Elliot DeNolf
95fcd13929 fix(db-*): drizzle enums, bump drizzle-kit (#7514)
- bumps drizzle-kit
- Fixes https://github.com/payloadcms/payload/issues/7492 Enum issue.
2024-08-05 14:53:21 -04:00
Jarrod Flesch
6141c5950b chore: improves plugin creation docs (#7515) 2024-08-05 14:50:53 -04:00
Elliot DeNolf
0040e1756c fix(cpa): adjust template file location detection (#7507)
Adjust template file location detection. This was causing issues when
run with `pnpm create` because it is not run from a `dist` directory.

```
┌   create-payload-app
│
◇   ────────────────────────────────────────────╮
│                                               │
│  Welcome to Payload. Let's create a project!  │
│                                               │
├───────────────────────────────────────────────╯
│
▲  Payload installation detected in current project.
│
◇  Upgrade Payload in this project?
│  Yes
│
◇  Using pnpm.
│
│
◇  Updating 7 Payload packages to v3.0.0-beta.73...
│
│    - payload
│    - @payloadcms/db-mongodb
│    - @payloadcms/db-postgres
│    - @payloadcms/next
│    - @payloadcms/richtext-lexical
│    - @payloadcms/richtext-slate
│    - @payloadcms/ui
│
◇  Payload packages updated successfully.
│
◇  Updating Payload Next.js files...
│
■  ENOENT: no such file or directory, copyfile '/Users/elliot/Library/pnpm/store/v3/tmp/dlx-99797/node_modules/.pnpm/create-payload-app@3.0.0-beta.73/templates/blank-3.0/src/app/(payload)' -> '/Users/elliot/dev/payload-3.0-demo/src/app/(payload)'
```
2024-08-05 16:28:13 +00:00
Jarrod Flesch
1ebd54b315 feat: allows loginWithUsername to not require username (#7480)
Allows username to be optional when using the new loginWithUsername
feature. This can be done by the following:

```ts
auth: {
  loginWithUsername: {
    requireUsername: false, // <-- new property, default true
    requireEmail: false, // default: false
    allowEmailLogin: true, // default false
  },
},
```
2024-08-05 11:35:01 -04:00
Jessica Chowdhury
cdb2072a6d fix: error thrown in version view when localization is false (#7502)
## Description

`const localeValues = locales.map((locale) => locale.value)`

This line was previously throwing an error in the version view when
localization is false. Changed to ensure locales exist before mapping
over them.

- [X] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [ ] Chore (non-breaking change which does not add functionality)
- [X] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] Change to the
[templates](https://github.com/payloadcms/payload/tree/main/templates)
directory (does not affect core functionality)
- [ ] Change to the
[examples](https://github.com/payloadcms/payload/tree/main/examples)
directory (does not affect core functionality)
- [ ] This change requires a documentation update

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [X] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-05 15:10:02 +00:00
Tylan Davis
68553ff974 feat!: updated admin UI (#7424)
## Description

- Updates admin UI with more condensed spacing throughout.
- Improves hover states and read-only states for various components.
- Removes the `Merriweather` font from `next/font` and replaces with
stack of system serif fonts and fallbacks (Georgia, etc). Closes #7257

## BREAKING CHANGES
- Custom components and styling that don't utilize Payload's CSS/SCSS
variables may need adjustments to match the updated styling.
- If you are using the `Merriweather` font, you will need to manually
configure `next/font` in your own project.

---------

Co-authored-by: Paul Popus <paul@nouance.io>
2024-08-05 15:08:00 +00:00
Willy Brauner
9a3bce1118 feat: expose useTableColumns hook (#7448)
fix #4990 (v3)

## Description

Expose
[useTableColumns](b160686fff/packages/ui/src/elements/TableColumns/index.tsx (L25))
hook from client exported members of the ui packages.

The use of this hook, covered the case of custom ListView creation which
was not possible due to the lack of possibility to select a file if we
were in the "list-draw" view.

With `useTableColumns` we can execute the `onClick` defined in
`TableColumnsProvider` witch allows the selection on the clicked file.


b160686fff/packages/ui/src/elements/ListDrawer/DrawerContent.tsx (L290-L296)

## Use case

CustomListView.tsx:
```ts
const CustomListView = () => {
  // ...

  const tableColumns = useTableColumns()
  
  const handleItemClicked = (doc) => {
    const onClick = tableColumns.columns[0].cellProps?.onClick
    if (typeof onClick === 'function') {
      // we are in "list-drawer" view, execute the onClick function
      onClick({
        cellData: undefined,
        collectionSlug: doc,
        rowData: doc,
      })
    } else {
      // we are in "collection-admin" view, push the new route with next/navigation
      void router.push(`${collectionSlug}/${doc.id}`)
    }
  }
 
  return  <div className={"list"}>
            {data.docs?.length > 0 && (
              <RelationshipProvider>
                {docs.map((e, i) => (
                  <div className={"item"} key={i} onClick={() => handleItemClicked(e)}>
                     // ...
                  </div>
                ))}
              </RelationshipProvider>
            )}
          </div>
} 
```

This video shows the click of a file inside a CustomListView, in the
case of an "admin-collection" view then a "list-drawer" view.


https://github.com/user-attachments/assets/8aa17af5-a7aa-49de-b988-fc0db7ac8e47

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

<!-- Please delete options that are not relevant. -->

- [x] Chore (non-breaking change which does not add functionality)
- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] Existing test suite passes locally with my changes
2024-08-05 14:52:47 +00:00
James Mikrut
005befcbe2 fix: #7488, cant deploy SQLite to Vercel (#7490)
## Description

Closes #7488 

Note - you'll also need to manually have `@libsql/client` installed in
your Next.js repository. This is not ideal, but it might be outside the
scope of what we can handle internally.

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.
2024-08-05 10:41:12 -04:00
Alessio Gravili
e65b6478c9 feat(richtext-lexical)!: upgrade lexical from 0.16.1 to 0.17.0 2024-08-05 09:58:27 -04:00
Elliot DeNolf
a79e92a145 chore(release): v3.0.0-beta.73 [skip ci] 2024-08-02 09:53:56 -04:00
Alessio Gravili
995f51d941 fix: too many RSC props were being passed, inflating initial HTML size (#7474)
The following config caused the html size to grow to 500mb:

```ts
import type { ArrayField, Block, CollectionConfig } from 'payload'

import { BlocksFeature, lexicalEditor } from '@payloadcms/richtext-lexical'

const richTextLayoutBlockGridBoxes2: ArrayField = {
  name: 'gridBx',
  labels: { singular: 'Grid Box', plural: 'Grid Boxes' },
  type: 'array',
  fields: [
    {
      name: 'gridBx',
      label: 'Grid Box Content',
      type: 'blocks',
      maxRows: 1,
      blocks: [],
    },
  ],
}

const richTextLayoutBlock2: Block = {
  slug: 'layout',
  interfaceName: 'RichTextLayoutBlock',
  labels: { singular: 'Layout', plural: 'Layout' },
  fields: [richTextLayoutBlockGridBoxes2],
}

const richTextBlock2: Block = {
  slug: 'rich-text',
  interfaceName: 'RichTextBlock',
  labels: { singular: 'Rich Text', plural: 'Rich Text' },
  fields: [
    {
      name: 'richTextContent',
      label: 'Rich Text',
      type: 'richText',
      required: true,
      editor: lexicalEditor({
        features: ({ defaultFeatures }) => [
          ...defaultFeatures,
          BlocksFeature({ blocks: [richTextLayoutBlock2] }),
        ],
      }),
    },
  ],
}

const richTextLayoutBlockGridBoxes1: ArrayField = {
  name: 'gridBx',
  labels: { singular: 'Grid Box', plural: 'Grid Boxes' },
  type: 'array',
  fields: [
    {
      name: 'gridBx',
      label: 'Grid Box Content',
      type: 'blocks',
      maxRows: 1,
      blocks: [richTextBlock2],
    },
  ],
}

const richTextLayoutBlock1: Block = {
  slug: 'layout',
  interfaceName: 'RichTextLayoutBlock',
  labels: { singular: 'Layout', plural: 'Layout' },
  fields: [richTextLayoutBlockGridBoxes1],
}

const richTextBlock1: Block = {
  slug: 'rich-text',
  interfaceName: 'RichTextBlock',
  labels: { singular: 'Rich Text', plural: 'Rich Text' },
  fields: [
    {
      name: 'richTextContent',
      label: 'Rich Text',
      type: 'richText',
      required: true,
      editor: lexicalEditor({
        features: ({ defaultFeatures }) => [
          ...defaultFeatures,
          BlocksFeature({ blocks: [richTextLayoutBlock1] }),
        ],
      }),
    },
  ],
}

const richTextLayoutBlockGridBoxes: ArrayField = {
  name: 'gridBx',
  labels: { singular: 'Grid Box', plural: 'Grid Boxes' },
  type: 'array',
  fields: [
    {
      name: 'gridBx',
      label: 'Grid Box Content',
      type: 'blocks',
      maxRows: 1,
      blocks: [richTextBlock1],
    },
  ],
}

const richTextLayoutBlock: Block = {
  slug: 'layout',
  interfaceName: 'RichTextLayoutBlock',
  labels: { singular: 'Layout', plural: 'Layout' },
  fields: [richTextLayoutBlockGridBoxes],
}

const richTextBlock: Block = {
  slug: 'rich-text',
  interfaceName: 'RichTextBlock',
  labels: { singular: 'Rich Text', plural: 'Rich Text' },
  fields: [
    {
      name: 'richTextContent',
      label: 'Rich Text',
      type: 'richText',
      required: true,
      editor: lexicalEditor({
        features: ({ defaultFeatures }) => [
          ...defaultFeatures,
          BlocksFeature({ blocks: [richTextLayoutBlock] }),
        ],
      }),
    },
  ],
}

const layoutBlockGridBoxes2: ArrayField = {
  name: 'gridBx',
  label: 'Grid Boxes',
  type: 'array',
  fields: [
    {
      name: 'gridBx',
      label: 'Grid Box Content',
      type: 'blocks',
      maxRows: 1,
      blocks: [richTextBlock],
    },
  ],
}

const layoutBlock2: Block = {
  slug: 'layout',
  interfaceName: 'LayoutBlock',
  labels: { singular: 'Layout', plural: 'Layout' },
  fields: [layoutBlockGridBoxes2],
}

const layoutBlockGridBoxes1: ArrayField = {
  name: 'gridBx',
  label: 'Grid Boxes',
  type: 'array',
  fields: [
    {
      name: 'gridBx',
      label: 'Grid Box Content',
      type: 'blocks',
      maxRows: 1,
      blocks: [layoutBlock2, richTextBlock],
    },
  ],
}

const layoutBlock1: Block = {
  slug: 'layout',
  interfaceName: 'LayoutBlock',
  labels: { singular: 'Layout', plural: 'Layout' },
  fields: [layoutBlockGridBoxes1],
}

const layoutBlockGridBoxes: ArrayField = {
  name: 'gridBx',
  labels: { singular: 'Grid Box', plural: 'Grid Boxes' },
  type: 'array',
  fields: [
    {
      name: 'gridBx',
      label: 'Grid Box Content',
      type: 'blocks',
      maxRows: 1,
      blocks: [layoutBlock1, richTextBlock],
    },
  ],
}

const layoutBlock: Block = {
  slug: 'layout',
  interfaceName: 'LayoutBlock',
  labels: { singular: 'Layout', plural: 'Layout' },
  fields: [layoutBlockGridBoxes],
}

export const Pages: CollectionConfig = {
  slug: 'pages',
  fields: [
    {
      name: 'content',
      type: 'blocks',
      blocks: [layoutBlock],
    },
  ],
}
```

---------

Co-authored-by: James <james@trbl.design>
2024-08-02 13:17:56 +00:00
Radosław Kłos
4d19e64961 feat: adds upload's relationship thumbnail (#7473)
## Description
https://github.com/payloadcms/payload/pull/5015 's version for beta
branch. @JessChowdhury

- [X] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

<!-- Please delete options that are not relevant. -->

- [X] New feature (non-breaking change which adds functionality)
- [X] This change requires a documentation update

## Checklist:

- [X] I have added tests that prove my fix is effective or that my
feature works
- [X] Existing test suite passes locally with my changes
- [X] I have made corresponding changes to the documentation
2024-08-02 14:03:12 +01:00
Elliot DeNolf
31143599f6 feat(cpa): add sqlite (#7470)
Add `sqlite` as an option for create-payload-app.
2024-08-01 12:50:14 -04:00
Jessica Chowdhury
f752804410 fix: set active nav item (#7467)
## Description

Nav items not displaying different style when active.

We were previously using `NavLink` which determines if the item is
active and applies the classname. Now we are using the standard `Link`
and need to add the `active` classname manually.

- [X] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [ ] Chore (non-breaking change which does not add functionality)
- [X] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] Change to the
[templates](https://github.com/payloadcms/payload/tree/main/templates)
directory (does not affect core functionality)
- [ ] Change to the
[examples](https://github.com/payloadcms/payload/tree/main/examples)
directory (does not affect core functionality)
- [ ] This change requires a documentation update

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [X] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-01 16:01:57 +00:00
Elliot DeNolf
a18d4061ea chore(release): v3.0.0-beta.72 [skip ci] 2024-08-01 10:48:31 -04:00
Dan Ribbens
449c16d28f fix(db-postgres): incorrect schema type on adapter (#7459)
fixes a db-postgres type issue that was introduced in
https://github.com/payloadcms/payload/pull/7453
2024-08-01 10:39:54 -04:00
Jessica Chowdhury
d307d627ab feat: adds restore as draft option to versions (#7100)
## Description

Adds option to restore a version as a draft.

1. Run `versions` test suite
2. Go to `drafts` and choose any doc with `status: published`
3. Open the version
4. See new `restore as draft` option

<img width="1693" alt="Screenshot 2024-07-12 at 1 01 17 PM"
src="https://github.com/user-attachments/assets/14d4f806-c56c-46be-aa93-1a2bd04ffd5c">

- [X] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [ ] Chore (non-breaking change which does not add functionality)
- [ ] Bug fix (non-breaking change which fixes an issue)
- [X] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] Change to the
[templates](https://github.com/payloadcms/payload/tree/main/templates)
directory (does not affect core functionality)
- [ ] Change to the
[examples](https://github.com/payloadcms/payload/tree/main/examples)
directory (does not affect core functionality)
- [ ] This change requires a documentation update

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [X] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-01 15:33:40 +01:00
Dan Ribbens
075819964d fix(db-postgres, db-sqlite): enum schema (#7453)
- updates drizzle-kit and drizzle-orm
- fix enum creation to fully support custom schemas
- sqlite by default will not use transactions
2024-07-31 16:42:00 -04:00
Dan Ribbens
1ec78a16f0 fix(db-postgres): localized array inside blocks field (#7457)
fixes #7371, #5240
2024-07-31 16:33:52 -04:00
Jarrod Flesch
290ffd3287 fix: validates password and confirm password on the server (#7410)
Fixes https://github.com/payloadcms/payload/issues/7380

Adjusts how the password/confirm-password fields are validated. Moves
validation to the server, adds them to a custom schema under the schema
path `${collectionSlug}.auth` for auth enabled collections.
2024-07-31 14:55:08 -04:00
Patrik
3d89508ce3 fix(ui): reincorporate basePath into logout component link (#7451)
## Description

Fixes issue where the `basePath` from the `next-config` was not
respected for the `logout` button link

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] Existing test suite passes locally with my changes
2024-07-31 11:00:02 -04:00
Elliot DeNolf
b160686fff ci: adjust canary release conditions 2024-07-31 00:39:22 -04:00
Elliot DeNolf
ba6ef6777f ci: auto release canary on success (#7444)
Automatically release canary on successful workflow.
2024-07-31 00:11:28 -04:00
Paul
febd7f7073 feat(ui): expose custom errors in deleteMany (#7438)
Closes https://github.com/payloadcms/payload/issues/7214
Exposes custom errors in the DeleteMany component so they can be more
descriptive:


![image](https://github.com/user-attachments/assets/f0c2f2e3-71a9-455f-9137-23eccfd21dbb)
2024-07-30 18:00:11 +00:00
Dan Ribbens
695ef32d1e feat(db-*): add defaultValues to database schemas (#7368)
## Description

Prior to this change, the `defaultValue` for fields have only been used
in the application layer of Payload. With this change, you get the added
benefit of having the database columns get the default also. This is
especially helpful when adding new columns to postgres with existing
data to avoid needing to write complex migrations. In MongoDB this
change applies the default to the Mongoose model which is useful when
calling payload.db.create() directly.

This only works for statically defined values.

🙏 A big thanks to @r1tsuu for the feature and implementation idea as I
lifted some code from PR https://github.com/payloadcms/payload/pull/6983

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] New feature (non-breaking change which adds functionality)
- [x] This change requires a documentation update

## Checklist:

- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [x] I have made corresponding changes to the documentation
2024-07-30 13:41:18 -04:00
Elliot DeNolf
b5b2bb1907 fix(db-postgres): proper migrations table detection query (#7436)
Fixes postgres sql query to detect migrations table.

`error: syntax error at or near "exists"`
2024-07-30 11:38:28 -04:00
Elliot DeNolf
6f5cf5d916 feat(cpa): warn on unsupported Next.js version (#7434)
Improves messaging if running an unsupported version of Next.js.

Closes #7430
2024-07-30 11:14:57 -04:00
Alessio Gravili
aaf3a39f7e chore: upgrade typescript from 5.5.3 to 5.5.4 (#7435)
TypeScript 5.5.4 apparently speeds up linting by a lot:
https://github.com/microsoft/TypeScript/issues/59101
2024-07-30 15:09:28 +00:00
Jessica Chowdhury
5ef2951829 fix: formats locales for version comparison view (#7433)
Closes #7381
2024-07-30 10:24:55 -04:00
Paul
a943487fca fix: hide force unlock button if the user has no permissions to interact with it (#7418) 2024-07-29 20:49:57 +00:00
Jarrod Flesch
3a941c7c8a chore: duplicates prev value PRs from v2 (#7414)
Updates V3 with V2 PR's
- previousVersion type https://github.com/payloadcms/payload/pull/6805
- tests from https://github.com/payloadcms/payload/pull/6805
2024-07-29 16:28:28 -04:00
Dan Ribbens
354588898f feat(db-*, payload): better transactions (#7395)
## Description

### payload
- Removes calls to beginTransaction and commitTransaction from read
operations

### db-sqlite, db-postgres
- beginTransaction() options are passed through and used to create a
transaction
- declare module type adds beginTransaction with proper transaction
config args for postgres and sqlite
2024-07-29 15:35:19 -04:00
Jessica Chowdhury
ada9978a8c fix: page param not getting reset when applying filters (#7243)
Closes #7188

In the collection list view, after adding a filter, the page number
should be reset since the doc count will have changed.

---------

Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
2024-07-29 13:25:43 -04:00
Jacob Fletcher
874279c530 fix(next): infinite loop when logging into root admin (#7412) 2024-07-29 12:57:57 -04:00
Paul
7ed6634bc5 fix: types for the 'validate' property across fields so internal validation functions can be reused (#7394)
Fixes the types for validate functions so that internal validation
functions can be re-used

Currently this has a type error
```ts
validate: (value, args) => {
  return text(value, args)
},
```
2024-07-29 12:36:28 -04:00
Michel v. Varendorff
09a0ee3ab9 fix: export default was not found in graphql (#6975) 2024-07-29 11:37:58 -04:00
Lynn Dylan Hurley
67acab2cd5 fix(searchPlugin): ensure search updates are unique to collection (#6363) 2024-07-29 11:33:59 -04:00
Jarrod Flesch
b3dc6cc811 chore: extends buildConfigWithDefaults to accept options arg (#7411) 2024-07-29 11:10:46 -04:00
Jarrod Flesch
5cd0c7ec7d fix: layout preferences for array/blocks were being saved twice in dev mode (#7396)
Fixes an issue where preferences for array/block collapsible's were not
being set correctly. React strict mode surfaced this issue.
2024-07-29 09:59:05 -04:00
Elliot DeNolf
cd592cb3a2 chore(release): v3.0.0-beta.71 [skip ci] 2024-07-29 08:43:45 -04:00
Dan Ribbens
6d066c2ba4 fix(db-sqlite): migration template errors (#7404)
- Fix migration template for sqlite
- Add declare for payload.db.drizzle as type LibSQLDatabase
- Correct drizzle snapshot version
2024-07-27 22:10:09 -04:00
Dan Ribbens
1dc428823a fix(db-postgres): migration template type error (#7403)
Fixes #7402

This fixes a regression from changes to the postgres migration template
that were incorrect. It also fixes other type errors for
`payload.db.drizzle` which needed to be declared for postgres to avoid
confusing it with Libsql for SQLite.
2024-07-27 21:52:36 -04:00
James Mikrut
c8da9b148c fix: merges headers safely in nextjs route handlers (#7399)
## Description

Merges headers safely within Payload-handled Next.js route handlers.
2024-07-27 16:34:06 +00:00
Jacob Fletcher
2021028d64 fix(ui): stacking drawers (#7397) 2024-07-27 09:33:31 -04:00
Paul
2ea56fe0f8 fix(docs): update import path for validation functions for fields (#7392) 2024-07-26 18:32:58 +00:00
Jacob Fletcher
ea16119af7 chore(cpa): replaces missing type assertion (#7391) 2024-07-26 14:13:46 -04:00
Jacob Fletcher
97837f0708 feat(ui)!: passes field props to custom components (#7360)
## Description

Currently, there is no way to read field props from within a custom
field component, i.e. `admin.components.Description`. For example, if
you set `maxLength: 100` on your field, your custom description
component cannot read it from `props.maxLength` or any other methods.
Because these components are rendered on the server, there is also no
way of using `admin.component.Field` to inject custom props yourself,
either. To support this, we can simply pass the base component props
into these components on the server, as expected. This has also led to
custom field component props becoming more strictly typed within the
config.

This change is considered breaking only because the types have changed.
This only affects you if you were previously importing the following
types into your own custom components. To migrate, simply change the
import paths for that type.

Old:
```ts
import type {
  ArrayFieldProps,
  ReducedBlock,
  BlocksFieldProps,
  CheckboxFieldProps,
  CodeFieldProps,
  CollapsibleFieldProps,
  DateFieldProps,
  EmailFieldProps,
  GroupFieldProps,
  HiddenFieldProps,
  JSONFieldProps,
  NumberFieldProps,
  PointFieldProps,
  RadioFieldProps,
  RelationshipFieldProps,
  RichTextComponentProps,
  RowFieldProps,
  SelectFieldProps,
  TabsFieldProps,
  TextFieldProps,
  TextareaFieldProps,
  UploadFieldProps,
  ErrorProps,
  FormFieldBase, 
  FieldComponentProps,
  FieldMap,
  MappedField,
  MappedTab,
  ReducedBlock,
} from '@payloadcms/ui'
```

New:
```ts
import type {
  FormFieldBase, 
  // etc.
} from 'payload'
```

Custom field components are now much more strongly typed. To make this
happen, an explicit type for every custom component has been generated
for every field type. The convention is to append
`DescriptionComponent`, `LabelComponent`, and `ErrorComponent` onto the
end of the field name, i.e. `TextFieldDescriptionComponent`. Here's an
example:

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

import React from 'react'

export const CustomDescription: TextFieldDescriptionComponent = (props) => {
  return (
    <div id="custom-field-description">{`The max length of this field is: ${props?.maxLength}`}</div>
  )
}
```

Here's the full list of all new types:

Label Components:

```ts
import type {
  ArrayFieldLabelComponent,
  BlocksFieldLabelComponent,
  CheckboxFieldLabelComponent,
  CodeFieldLabelComponent,
  CollapsibleFieldLabelComponent,
  DateFieldLabelComponent,
  EmailFieldLabelComponent,
  GroupFieldLabelComponent,
  HiddenFieldLabelComponent,
  JSONFieldLabelComponent,
  NumberFieldLabelComponent,
  PointFieldLabelComponent,
  RadioFieldLabelComponent,
  RelationshipFieldLabelComponent,
  RichTextFieldLabelComponent,
  RowFieldLabelComponent,
  SelectFieldLabelComponent,
  TabsFieldLabelComponent,
  TextFieldLabelComponent,
  TextareaFieldLabelComponent,
  UploadFieldLabelComponent
} from 'payload'
```

Error Components:

```tsx
import type {
  ArrayFieldErrorComponent,
  BlocksFieldErrorComponent,
  CheckboxFieldErrorComponent,
  CodeFieldErrorComponent,
  CollapsibleFieldErrorComponent,
  DateFieldErrorComponent,
  EmailFieldErrorComponent,
  GroupFieldErrorComponent,
  HiddenFieldErrorComponent,
  JSONFieldErrorComponent,
  NumberFieldErrorComponent,
  PointFieldErrorComponent,
  RadioFieldErrorComponent,
  RelationshipFieldErrorComponent,
  RichTextFieldErrorComponent,
  RowFieldErrorComponent,
  SelectFieldErrorComponent,
  TabsFieldErrorComponent,
  TextFieldErrorComponent,
  TextareaFieldErrorComponent,
  UploadFieldErrorComponent
} from 'payload'
```

Description Components:

```tsx
import type {
  ArrayFieldDescriptionComponent,
  BlocksFieldDescriptionComponent,
  CheckboxFieldDescriptionComponent,
  CodeFieldDescriptionComponent,
  CollapsibleFieldDescriptionComponent,
  DateFieldDescriptionComponent,
  EmailFieldDescriptionComponent,
  GroupFieldDescriptionComponent,
  HiddenFieldDescriptionComponent,
  JSONFieldDescriptionComponent,
  NumberFieldDescriptionComponent,
  PointFieldDescriptionComponent,
  RadioFieldDescriptionComponent,
  RelationshipFieldDescriptionComponent,
  RichTextFieldDescriptionComponent,
  RowFieldDescriptionComponent,
  SelectFieldDescriptionComponent,
  TabsFieldDescriptionComponent,
  TextFieldDescriptionComponent,
  TextareaFieldDescriptionComponent,
  UploadFieldDescriptionComponent
} from 'payload'
```

This PR also:
- Standardizes the `FieldBase['label']` type with a new `LabelStatic`
type. This makes type usage much more consistent across components.
- Simplifies some of the typings in the field component map, removes
unneeded `<Omit>`, etc.
- Fixes misc. linting issues around voiding promises

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] New feature (non-breaking change which adds functionality)

## Checklist:

- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [x] I have made corresponding changes to the documentation
2024-07-26 14:03:25 -04:00
Paul
e734d51760 chore(ui)!: update the names of internal components so that they respect eslint rules (#7362)
So `_Upload` becomes `UploadComponent` which doesnt break the naming
convention of react components and **we no longer export these internal
components**
2024-07-26 17:50:23 +00:00
Patrik
5655266daa fix(ui): handle abort() call signal error (#7390)
## Description

Swallows `.abort()` call signal errors

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] Existing test suite passes locally with my changes
2024-07-26 13:16:22 -04:00
James Mikrut
f9e5573c1e feat: adds keepAfterRead to plugin-relationship-objectid (#7388)
## Description

Duplicate of
https://github.com/payloadcms/plugin-relationship-object-ids/pull/6 for
3.x
2024-07-26 15:39:39 +00:00
Paul
e823051a8e fix(ui): spacing in row fields by using gap instead of inner margins (#7387) 2024-07-26 15:34:30 +00:00
Elliot DeNolf
49df61d9ec chore(release): v3.0.0-beta.70 [skip ci] 2024-07-26 11:16:04 -04:00
Paul
4704c8db2a feat(templates): add live preview breakpoints for mobile, tablet and desktop to website template (#7384) 2024-07-26 14:41:59 +00:00
Elliot DeNolf
a64f37e014 feat(cpa): support next.config.ts (#7367)
Support new `next.config.ts` config file.

Had to do some weird gymnastics around `swc` in order to use it within
unit tests. Had to pass through the `parsed.span.end` value of any
previous iteration and account for it.

Looks to be an open issue here:
https://github.com/swc-project/swc/issues/1366

Fixes #7318
2024-07-26 10:33:46 -04:00
Elliot DeNolf
55c6ce92b0 fix(db-postgres): properly reference drizzle createTableName function (#7383)
Fix incorrect relative import of drizzle package's `createTableName`
function. Now uses proper package import.

Fixes #7373
2024-07-26 10:08:31 -04:00
Elliot DeNolf
2ecbcee378 chore(release): v3.0.0-beta.69 [skip ci] 2024-07-25 22:17:04 -04:00
James Mikrut
70f2e1698a fix: filterOptions for upload fields (#7347)
## Description

Fixes uploads `filterOptions` not being respected in the Payload admin
UI.

Needs a test written, fixes to types in build, as well as any tests that
fail due to this change in CI.

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-07-25 21:42:36 +00:00
Patrik
8ba39aa5ca fix(db-mongodb): adds new optional collation feature flag behind mongodb collation option (#7361)
## Description

V2 PR [here](https://github.com/payloadcms/payload/pull/7359)

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [x] This change requires a documentation update

## Checklist:

- [x] Existing test suite passes locally with my changes
- [x] I have made corresponding changes to the documentation
2024-07-25 12:38:18 -04:00
Elliot DeNolf
f8c79d2f84 ci: label pr on open 2024-07-25 10:48:54 -04:00
Paul
128d72185d fix(ui): hide 'Create new' button entirely if user has no access to create a media item (#7348)
Makes it so that if you don't have access to create a new media you
don't get the button shown at all:

![image](https://github.com/user-attachments/assets/2a9c1b24-a4cb-41f3-9145-514cd51a2f1f)
2024-07-25 14:35:43 +00:00
Jarrod Flesch
abc786d864 chore: removes todo comment in AuthProvider (#7356) 2024-07-25 10:06:11 -04:00
Elliot DeNolf
791fa68820 ci: disable app-build-with-packed 2024-07-24 16:34:03 -04:00
Jarrod Flesch
2796d2100f fix: attempts to use query.locale when present in createLocalReq (#7345)
Fixes https://github.com/payloadcms/payload/issues/7341

req.locale was incorrectly set, stemming from initPage, where
req.query.locale was not being used if present inside the
`createLocaleReq` function.
2024-07-24 16:30:05 -04:00
Jarrod Flesch
cbac62a36f fix: relaxes equality check for relationship options in filter (#7343)
Fixes https://github.com/payloadcms/payload/issues/7271

When extracting the value from the querystring, it is _always_ a string.
We were using a strict equality check which would cause the filter
options to never find the correct option. This caused an infinite loop
when using PG as ID's are numbers by default.
2024-07-24 15:53:29 -04:00
Patrik
b5afc62e14 feat(payload): allows metadata to be appended to the file of the output media (#7293)
## Description

Fixes #6951 

`Feat`: Adds new prop `withMetadata` to `uploads` config that allows the
user to allow media metadata to be appended to the file of the output
media.

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [x] This change requires a documentation update

## Checklist:

- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [x] I have made corresponding changes to the documentation
2024-07-24 15:32:39 -04:00
Elliot DeNolf
0627272d6c chore(scripts): adjust release notes indent 2024-07-24 14:27:36 -04:00
Ritsu
51f1c8e7e8 fix(db-postgres): localized groups/tabs and nested fields (#6158)
---------

Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
2024-07-24 13:57:10 -04:00
Dan Ribbens
09ad6e4280 feat(drizzle): abstract shared sql code to new package (#7320)
- Abstract shared sql code to a new drizzle package
- Adds sqlite package, not ready to publish until drizzle patches some
issues
- Add `transactionOptions` to allow customizing or disabling db
transactions
- Adds "experimental" label to the `schemaName` property until drizzle
patches an issue
2024-07-24 12:43:29 -04:00
Paul
c129c10f0f fix: some email adapters not working if they're promises due to config sanitisation (#7326) 2024-07-24 14:23:04 +00:00
Jacob Fletcher
904ec0160e feat: adds @payloadcms/live-preview-vue to release pipeline (#7328) 2024-07-24 10:07:34 -04:00
Jessica Chowdhury
b2814eb67c fix: misc issues with loginWithUsername (#7311)
- improves types
- fixes create-first-user fields
2024-07-23 15:14:12 -04:00
Paul
c405e5958f fix(ui): email field now correctly renders autocomplete attribute (#7322)
Adds test as well for the email field
2024-07-23 18:57:53 +00:00
Jacob Fletcher
a35979f74e fix(plugin-stripe): properly types async webhooks (#7317) 2024-07-23 14:30:09 -04:00
Jacob Fletcher
863abc0e6b feat(next): root admin (#7276) 2024-07-23 13:44:44 -04:00
Paul
b9cf6c73a9 fix(ui): Where query selectors for checkboxes are now translated (#7309)
Fixes https://github.com/payloadcms/payload/issues/7204
2024-07-23 17:12:18 +00:00
Jessica Chowdhury
f2b3305cb0 fix: first version doc throws error (#7314)
## Description

The first version document throws an error because `latestPublished` and
`latestDraft` are undefined.

- [X] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [X] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [X] Existing test suite passes locally with my changes
2024-07-23 16:36:16 +00:00
Patrik
b3e8ddf302 fix(db-mongodb): removes precedence of regular chars over international chars in sort (#7294)
## Description

V2 PR [here](https://github.com/payloadcms/payload/pull/6923)

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
2024-07-23 09:03:00 -04:00
Jacob Fletcher
b6d4bc4d37 docs: cleanup to individual field docs (#7202) 2024-07-22 23:46:06 -04:00
Elliot DeNolf
83ad453a89 fix(cpa): check cmd exists after first checking flag and lock file (#7297)
Adjust logic for determining package manager. Needed to move command
exists logic to be evaluated only after other possibilities were
exhausted.

Closes #7290
2024-07-22 22:11:44 -04:00
Elliot DeNolf
4e6a7d489c chore(scripts): delete-recursively output spacing 2024-07-22 21:26:21 -04:00
Elliot DeNolf
a8d88b8238 chore(release): v3.0.0-beta.68 [skip ci] 2024-07-22 16:05:04 -04:00
Jarrod Flesch
5aa3283dc0 fix: search plugin localized fields (#7292) 2024-07-22 15:47:39 -04:00
Alessio Gravili
45844789f2 feat: upgrade pino and pino-pretty, clean up hacky esm imports (#7291)
Doesn't look like those hacky esm-cjs imports are needed anymore.

These major pino releases only drop Node.js version support for versions
which payload doesn't support anyways.
2024-07-22 15:11:34 -04:00
Alessio Gravili
79975f48cf chore: ensure the correct next & react versions are installed in templates and core (#7283)
Some package.json's were on older or mismatching Next.js / React
versions. This includes other Next.js packages like @next/env
2024-07-22 18:33:54 +00:00
Paul
bba7cf37f8 fix(templates): website template building error with postgres number IDs (#7281) 2024-07-22 17:40:58 +00:00
Paul
1ae71a3d24 fix(ui): not updating permissions when locale changes (#7245)
Closes https://github.com/payloadcms/payload/issues/7163
2024-07-22 17:31:20 +00:00
Alessio Gravili
e83eb99436 feat: remove joi schema validation (#7226)
We do not really need runtime joi schema validation - this is what TypeScript is for. If people are ignoring TypeScript errors in your schema, or JavaScript errors, that is their fault and does not warrant an extra dependency (joi), lots of code to maintain, as well as slower startups.

If we wanna keep runtime schema validation, we should switch to zod so that we can generate TypeScript types based on the schema and do not have to manually maintain config properties in 2 different places (types & schema).

**joi PROs:**
- Safety for JavaScript-only evangelists messing up their schema
- Safety for people putting @ts-expect-error or `as any` everywhere in their code

**joi CONs:**
- Larger bundle size
- More Modules
- Slower Compilation Speed in dev. Worse DX
- Slower Startup (it needs to validate) in dev. Worse DX
- More code to maintain. For every schema change we'll have to change the types AND the joi schema
- TypeScript already throws proper errors if you mess up your schema. Why have runtime errors?
- The errors are bad. They might tell you what field has an issue, but they do not tell you what exactly is wrong. You have probably seen those "Field XY, value is incorrect" errors - and value could mean anything. Worse DX
- Having extra properties in your schema, even if they are useless, doesn't cause any harm

Cons outweigh the pros
2024-07-22 13:22:54 -04:00
Dan Ribbens
f50e599684 chore: add index to status for versions (#6257) 2024-07-22 13:13:09 -04:00
Dan Ribbens
7dab75d85e chore: make ui bundle script windows compatible (#7197) 2024-07-22 13:10:07 -04:00
Alessio Gravili
c45fbb9149 feat!: 700% faster deepCopyObject, refactor deep merging and deep copying, type improvements (#7272)
**BREAKING:**
- The `deepMerge` exported from payload now handles more complex data and
is slower. The old, simple deepMerge is now exported as `deepMergeSimple`
- `combineMerge` is no longer exported. You can use
`deepMergeWithCombinedArrays` instead
- The behavior of the exported `deepCopyObject` and `isPlainObject` may
be different and more reliable, as the underlying algorithm has changed
2024-07-22 13:01:52 -04:00
Patrik
2c16c608ba fix(payload): resizes images first before applying focal point (#7277)
Fixes #7275
2024-07-22 12:28:35 -04:00
Paul
c3f6c81dc6 chore: add custom ID warning about forbidden characters (#7268) 2024-07-22 02:23:53 +00:00
Alessio Gravili
a7b0f8ba36 feat!: new server-only, faster and immediate autoLogin (#7224)
- When autoLogin is enabled, it will no longer flash an unresponsive
"login" screen. Instead, it will straight up open the admin panel.
That's because, on the server, we will now always & immediately see the
user as authenticated, thus no initial login view is pushed to the
client until the client component sends the auth request anymore. Less
useless requests. Additionally, jwt verification is now completely
skipped
- No more auto-login related frontend code. autoLogin handling has been
removed from the frontend `Auth` component
- less code to maintain, this is way simpler now

**For reviewers:**
- The new logic for autoFill without prefillOnly is here: [jwt auth
strategy](https://github.com/payloadcms/payload/pull/7224/files#diff-7d40839079a8b2abb58233e5904513ab321023a70538229dfaf1dfee067dc8bfR21)
- The new logic for autoFill with prefillOnly is here: [Server Login
View](https://github.com/payloadcms/payload/pull/7224/files#diff-683770104f196196743398a698fbf8987f00e4426ca1c0ace3658d18ab80e82dL72)
=> [Client Login
Form](https://github.com/payloadcms/payload/pull/7224/files#diff-ac3504d3b3b0489455245663649bef9e84477bf0c1185da5a4d3a612450f01eeL20)

**BREAKING**
`autoLogin` without `prefillOnly` set now also affects graphQL/Rest
operations. Only the user specified in `autoLogin` will be returned.
Within the graphQL/Rest/Local API, this should still allow you to
authenticate with a different user, as the autoLogin user is only used
if no token is set.
2024-07-20 23:25:50 +00:00
Paul
014ee1a1b2 feat(ui): change autosave logic to send updates as soon as possible, improving live preview speed (#7201)
Now has a minimum animation time for the autosave but it fires off the
send events sooner to improve the live preview timing.
2024-07-19 15:24:53 -04:00
Patrik
cf6da0186b chore(translations, ui): updates addImage translation to addFile translation (#7231) 2024-07-19 13:36:37 -04:00
Jacob Fletcher
18063bd256 chore(examples): proper module resolution and migrations for multi-tenant single-domain example (#7240) 2024-07-19 13:18:13 -04:00
Paul
76b3075369 feat: update reserved fields name check to be more comprehensive and only check top level fields (#7235)
Continuation of https://github.com/payloadcms/payload/pull/7179
2024-07-19 15:53:00 +00:00
Jacob Fletcher
3d63ce94bb fix: api errors not populating in prod (#7232) 2024-07-19 11:42:53 -04:00
Paul
f8a5103ed7 chore(docs): update rest API handler to async (#7237)
Closes https://github.com/payloadcms/payload/issues/7077
2024-07-19 15:41:10 +00:00
Paul
2bd53a06eb chore(templates): add react cache to queryPostBySlug in website template (#7219) 2024-07-18 18:20:05 +00:00
Elliot DeNolf
442518dbc9 ci: make release script synchronous to ensure consistency 2024-07-18 14:09:36 -04:00
Elliot DeNolf
d3131122db chore(release): v3.0.0-beta.67 [skip ci] 2024-07-18 14:00:49 -04:00
Alessio Gravili
6d0dfeafc8 chore: ensure fs operations in bundle scripts finish in sync (#7218)
Hopefully fixes broken releases
2024-07-18 13:44:26 -04:00
Patrik
00771b1f2a fix(ui): uploading from drawer & focal point positioning (#7117)
Fixes #7101
Fixes #7006

Drawers were sending duplicate query params. This new approach modeled after the fix in V2, ensures that each drawer has its own action url created per document and the query params will be created when that is generated.

Also fixes the following:
- incorrect focal point cropping
- generated filenames for animated image names used incorrect heights
2024-07-18 13:43:53 -04:00
Jarrod Flesch
448186f374 chore: use href for locale switching, warns user before leaving (#7215)
Opts to use links instead of router.replace when switching locales. The
main benefit is now the user will be warned if they have changes and
want to switch locales. Before it would switch locales and they would
lose any unsaved changes in the locale they came from.
2024-07-18 12:59:27 -04:00
Elliot DeNolf
0ada3df220 chore(release): v3.0.0-beta.66 [skip ci] 2024-07-18 12:25:49 -04:00
Jarrod Flesch
478fb8d3fd fix: cherry picks lockUntil fix from #6052 (#7213) 2024-07-18 12:14:31 -04:00
Jacob Fletcher
700baf1899 fix: aliases AfterMe, AfterLogout, and AfterRefresh hook types (#7216) 2024-07-18 15:49:50 +00:00
Jarrod Flesch
7b3b02198c feat: ability to login with email, username or both (#7086)
`auth.loginWithUsername`:

```ts
auth: {
  loginWithUsername: {
    allowEmailLogin: true, // default: false
    requireEmail: false, // default: false
  }
}
```

#### `allowEmailLogin`
This property will allow you to determine if users should be able to
login with either email or username. If set to `false`, the default
value, then users will only be able to login with usernames when using
the `loginWithUsername` property.

#### `requireEmail`
Require that users also provide emails when using usernames.
2024-07-18 10:29:44 -04:00
Paul
a3af3605f0 fix(templates): bad import in website seed script (#7198) 2024-07-17 18:20:43 +00:00
Paul
502548a581 feat: add db idType to generated payload types (#7186)
Makes it so generated types now includes a `db` object with `idType` set
to `string` or `number` depending on the database

```ts
db: {
  defaultIDType: number;
};
```
2024-07-17 18:01:28 +00:00
Alessio Gravili
1fe6761d43 fix: maxListenersExceeded warning due to atomically, which is a peerdep of conf (#7182)
The conf dependency being bundled (not even executed) causes frequent
HMR runs (around 10+) to throw multiple MaxListenersExceeded warnings in
the console.

This PR
- fixes telemetry which was previously broken (threw an error which we
ignored) due to a conf version upgrade
- Removes the conf dependency (which is large and comes with a lot of
unneeded dependencies from functionality we don't need, like dot
notation or ajv validation). The important parts of the source code were
copied over - it's now dependency-free
- makes sure we only register the Next.js HMR websocket listener once,
by adding it to the cache

Before this PR:
![CleanShot 2024-07-16 at 19 35
22](https://github.com/user-attachments/assets/cfd926b7-fe5d-440a-9b35-91f61eaa69fd)


After this PR:

![CleanShot 2024-07-16 at 19 37
41](https://github.com/user-attachments/assets/f5d0f0f3-4e00-4d28-8e32-be42db2f5f6c)

Canary: 3.0.0-canary.ca3dd1c
2024-07-17 13:19:08 -04:00
Paul
f909f0663b fix(ui): search queries remain between navigation (#7169)
Closes https://github.com/payloadcms/payload/issues/7085
2024-07-17 17:17:46 +00:00
Jacob Fletcher
edb501349f docs: improves authentication docs (#7195) 2024-07-17 12:52:41 -04:00
Alessio Gravili
4ff8b20ddb chore(templates): clean up templates dependencies (#7139)
- use react 19 types
- no need for dotenv - next has their own dotenv file loader
- disable deprecation warnings by default (newer node version spam you
with it)
- disable turbo by default as hmr is broken and we cannot test against
it yet
- remove ts-node mention in tsconfig as it's not used anymore
- remove unused packages
- [fix: potential seed issues due to parallel payload operations being
on the same
transaction](f899f6a408)
and
b3b565dd75
@DanRibbens can you sense-check this? I do remember that anything
running in parallel should never be on the same transaction

---------

Co-authored-by: Paul Popus <paul@nouance.io>
2024-07-17 02:43:58 +00:00
Alessio Gravili
fe23ca5b1a fix(richtext-lexical): slash menu keyboard navigation not triggering auto-scroll (#7185)
`ref` was not added to internal slash menu items correctly.

Works as expected now:
![CleanShot 2024-07-16 at 22 05
41](https://github.com/user-attachments/assets/cfb32ec8-a449-41a7-a556-1e5ac365c6bc)
2024-07-17 02:30:04 +00:00
Alessio Gravili
8fdd88bd66 fix: webpack error if dbName or enumName was set (#7184)
Something like this:

```ts
  {
    name: 'select',
    type: 'select',
    dbName: ({ tableName }) => `${tableName}_customSelect`,
    enumName: 'selectEnum',
    hasMany: true,
    options: ['a', 'b', 'c'],
},
```
        
caused the "Functions cannot be passed directly to Client Components"
error, as the dbName function was sent to the client.

Now, you can run `pnpm dev database` again without it erroring
2024-07-17 01:02:42 +00:00
Alessio Gravili
676dfa3ecf feat(richtext-lexical): inline blocks (#7102) 2024-07-17 00:42:36 +00:00
Jessica Chowdhury
1ea2e323bc fix(ui): date field background color specificity (#7181)
## Description

Fixes `date` field background in dark mode.

Before:
<img width="464" alt="Screenshot 2024-07-16 at 5 22 42 PM"
src="https://github.com/user-attachments/assets/90235512-bd97-4b0a-b7b8-3e4ce49a8ba2">

After:
<img width="502" alt="Screenshot 2024-07-16 at 5 22 53 PM"
src="https://github.com/user-attachments/assets/ce3f5bc9-8693-4fc8-a0e3-d0042a92756f">

- [X] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [X] Chore (non-breaking change which does not add functionality)
2024-07-16 21:36:34 +00:00
Jessica Chowdhury
8fb17c2752 fix: version comparison view showing empty localized fields (#7180)
## Description

Localized fields show no data for the base comparison data in the
version comparison view.

Before:
<img width="1419" alt="Screenshot 2024-07-16 at 4 48 45 PM"
src="https://github.com/user-attachments/assets/c4c063a6-41c1-41a5-92b3-ff7d1febe9f1">

After:
<img width="1382" alt="Screenshot 2024-07-16 at 4 46 31 PM"
src="https://github.com/user-attachments/assets/bbfa9faf-2753-450d-a911-fbbca27ab051">

- [X] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [X] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [X] Existing test suite passes locally with my changes
2024-07-16 21:08:48 +00:00
Jacob Fletcher
2d96a1f0b6 docs: misc improvements to high-level docs (#7177) 2024-07-16 15:47:56 -04:00
Paul
2f0aa83a93 fix: localised relationship fields (#7178)
Fixes the issue where locale is not passed into the relationship field
resulting in documents without titles in some situations


![image](https://github.com/user-attachments/assets/67f0a70c-29a0-4f54-a395-f4aa9b132d6f)
2024-07-16 19:22:37 +00:00
Jacob Fletcher
0371aea711 docs: moves collection and global admin options to admin docs (#7168) 2024-07-16 12:08:21 -04:00
Alessio Gravili
36ae125caf chore(richtext-lexical): adjust error message when loading the editor on unmigrated data (#7170) 2024-07-16 16:07:53 +00:00
Jarrod Flesch
fa07b317b1 chore(examples): updates to multi tenant single domain example (#7165) 2024-07-16 09:06:46 -04:00
Alessio Gravili
08f50bb441 chore: run esbuild scripts in sync, hopefully fixing publishing issues (#7159)
We are suspecting that operations within those esbuild scripts are not
awaited properly - potentially causing issues in the publish script,
publishing the next package without any built .js files
2024-07-15 17:31:48 -04:00
Jacob Fletcher
2925c3bb90 docs: root hooks (#7160) 2024-07-15 17:15:34 -04:00
Alessio Gravili
c6da04a061 feat(next): strongly type getNextRequestI18n (#7157)
Fixes https://github.com/payloadcms/payload/issues/7137
2024-07-15 20:48:17 +00:00
Alessio Gravili
809ae41725 chore(richtext-lexical): add e2e test which reproduces #7128 (#7156)
Fix for this is in separate PR:
https://github.com/payloadcms/payload/pull/7155
2024-07-15 20:47:03 +00:00
Elliot DeNolf
ee6ab214a5 chore(release): v3.0.0-beta.65 [skip ci] 2024-07-15 16:29:22 -04:00
2058 changed files with 65523 additions and 57268 deletions

21
.github/CODEOWNERS vendored
View File

@@ -1,24 +1,23 @@
# Order matters. The last matching pattern takes precedence.
# Approvals are not required currently but may be enabled in the future.
### Package Exports ###
/**/exports/ @denolfe @jmikrut
/**/exports/ @denolfe @jmikrut @DanRibbens
### Packages ###
/packages/richtext-*/ @AlessioGr
/packages/plugin-cloud*/ @denolfe
/packages/email-*/ @denolfe
/packages/storage-*/ @denolfe
/packages/create-payload-app/ @denolfe
/packages/eslint-*/ @denolfe
/packages/plugin-cloud*/src/ @denolfe
/packages/email-*/src/ @denolfe
/packages/storage-*/src/ @denolfe
/packages/create-payload-app/src/ @denolfe
/packages/eslint-*/ @denolfe @AlessioGr
### Templates ###
/templates/ @jacobsfletch @denolfe
/templates/_data/ @denolfe
/templates/_template/ @denolfe
### Build Files ###
/**/package.json @denolfe
/tsconfig.json @denolfe
/**/tsconfig*.json @denolfe
/jest.config.js @denolfe
/**/jest.config.js @denolfe
@@ -26,5 +25,5 @@
/package.json @denolfe
/scripts/ @denolfe
/.husky/ @denolfe
/.vscode/ @denolfe
/.vscode/ @denolfe @AlessioGr
/.github/ @denolfe

View File

@@ -9,7 +9,7 @@ inputs:
pnpm-version:
description: 'The pnpm version to use'
required: true
default: 8.15.7
default: 9.7.0
runs:
using: composite
@@ -25,7 +25,7 @@ runs:
node-version: ${{ inputs.node-version }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ inputs.pnpm-version }}
run_install: false

View File

@@ -18,7 +18,7 @@ concurrency:
env:
NODE_VERSION: 18.20.2
PNPM_VERSION: 8.15.7
PNPM_VERSION: 9.7.1
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
NEXT_TELEMETRY_DISABLED: 1 # Disable Next telemetry
@@ -74,7 +74,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
@@ -120,7 +120,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
@@ -167,7 +167,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
@@ -196,6 +196,7 @@ jobs:
- postgres-custom-schema
- postgres-uuid
- supabase
- sqlite
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
@@ -206,6 +207,9 @@ jobs:
AWS_REGION: us-east-1
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 25
# https://github.com/actions/virtual-environments/issues/1187
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
@@ -216,17 +220,12 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
- name: Restore build
uses: actions/cache@v4
timeout-minutes: 10
with:
path: ./*
key: ${{ github.sha }}-${{ github.run_number }}
- run: pnpm install
- name: Start LocalStack
run: pnpm docker:start
@@ -292,6 +291,7 @@ jobs:
- access-control
- admin__e2e__1
- admin__e2e__2
- admin-root
- auth
- field-error-states
- fields-relationship
@@ -330,7 +330,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
@@ -369,7 +369,7 @@ jobs:
run: pnpm exec playwright install-deps chromium
- name: E2E Tests
run: PLAYWRIGHT_JSON_OUTPUT_NAME=results_${{ matrix.suite }}.json pnpm test:e2e ${{ matrix.suite }}
run: PLAYWRIGHT_JSON_OUTPUT_NAME=results_${{ matrix.suite }}.json pnpm test:e2e:prod:ci ${{ matrix.suite }}
env:
PLAYWRIGHT_JSON_OUTPUT_NAME: results_${{ matrix.suite }}.json
NEXT_TELEMETRY_DISABLED: 1
@@ -390,6 +390,7 @@ jobs:
# job-summary: true
app-build-with-packed:
if: false # Disable until package resolution in tgzs can be figured out
runs-on: ubuntu-latest
needs: build
@@ -404,7 +405,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
@@ -417,15 +418,15 @@ jobs:
key: ${{ github.sha }}-${{ github.run_number }}
- name: Start MongoDB
uses: supercharge/mongodb-github-action@1.10.0
uses: supercharge/mongodb-github-action@1.11.0
with:
mongodb-version: 6.0
- name: Pack and build app
run: |
set -ex
pnpm run script:pack --dest templates/blank-3.0
cd templates/blank-3.0
pnpm run script:pack --dest templates/blank
cd templates/blank
cp .env.example .env
ls -la
pnpm add ./*.tgz --ignore-workspace
@@ -448,7 +449,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
@@ -489,7 +490,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Start MongoDB
uses: supercharge/mongodb-github-action@1.10.0
uses: supercharge/mongodb-github-action@1.11.0
with:
mongodb-version: 6.0
@@ -517,7 +518,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
@@ -546,3 +547,16 @@ jobs:
steps:
- if: ${{ always() && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) }}
run: exit 1
publish-canary:
name: Publish Canary
runs-on: ubuntu-latest
needs:
- all-green
steps:
# debug github.ref output
- run: |
echo github.ref: ${{ github.ref }}
echo isBeta: ${{ github.ref == 'refs/heads/beta' }}
echo isMain: ${{ github.ref == 'refs/heads/main' }}

View File

@@ -38,6 +38,7 @@ jobs:
db-\*
db-mongodb
db-postgres
db-sqlite
email-nodemailer
eslint
graphql
@@ -101,3 +102,18 @@ jobs:
with:
header: pr-title-lint-error
delete: true
label-pr-on-open:
name: label-pr-on-open
runs-on: ubuntu-latest
steps:
- name: Tag with main branch with v2
if: github.event.action == 'opened' && github.event.pull_request.base.ref == 'main'
uses: actions-ecosystem/action-add-labels@v1
with:
labels: v2
- name: Tag with beta branch with v3
if: github.event.action == 'opened' && github.event.pull_request.base.ref == 'beta'
uses: actions-ecosystem/action-add-labels@v1
with:
labels: v3

View File

@@ -7,7 +7,7 @@ on:
env:
NODE_VERSION: 18.20.2
PNPM_VERSION: 8.15.7
PNPM_VERSION: 9.7.1
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
NEXT_TELEMETRY_DISABLED: 1 # Disable Next telemetry

14
.gitignore vendored
View File

@@ -5,6 +5,7 @@ dist
!/.idea/runConfigurations
!/.idea/payload.iml
test/packed
test-results
.devcontainer
.localstack
@@ -22,6 +23,10 @@ meta_shared.json
# Ignore test directory media folder/files
/media
test/media
*payloadtests.db
*payloadtests.db-journal
*payloadtests.db-shm
*payloadtests.db-wal
/versions
# Created by https://www.toptal.com/developers/gitignore/api/node,macos,windows,webstorm,sublimetext,visualstudiocode
@@ -149,6 +154,7 @@ out
# Nuxt.js build / generate output
.nuxt
dist
dist_optimized
# Gatsby files
.cache/
@@ -296,3 +302,11 @@ $RECYCLE.BIN/
/build
.swc
app/(payload)/admin/importMap.js
test/live-preview/app/(payload)/admin/importMap.js
/test/live-preview/app/(payload)/admin/importMap.js
test/admin-root/app/(payload)/admin/importMap.js
/test/admin-root/app/(payload)/admin/importMap.js
test/app/(payload)/admin/importMap.js
/test/app/(payload)/admin/importMap.js
test/pnpm-lock.yaml

7
.idea/payload.iml generated
View File

@@ -26,6 +26,7 @@
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/next/.swc" />
<excludeFolder url="file://$MODULE_DIR$/packages/next/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/next/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/payload/fields" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-cloud-storage/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-cloud-storage/dist" />
@@ -75,8 +76,12 @@
<excludeFolder url="file://$MODULE_DIR$/packages/ui/.swc" />
<excludeFolder url="file://$MODULE_DIR$/packages/ui/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/ui/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/drizzle/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/drizzle/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/db-sqlite/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/db-sqlite/dist" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
</module>

View File

@@ -1,8 +1,13 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Dev Fields" type="NodeJSConfigurationType" application-parameters="--no-deprecation fields" path-to-js-file="test/dev.js" working-dir="$PROJECT_DIR$">
<envs>
<env name="NODE_OPTIONS" value="--no-deprecation" />
</envs>
<configuration default="false" name="Run Dev Fields" type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="dev" />
</scripts>
<arguments value="fields" />
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>

View File

@@ -1,8 +1,13 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Dev _community" type="NodeJSConfigurationType" application-parameters="--no-deprecation _community" path-to-js-file="test/dev.js" working-dir="$PROJECT_DIR$">
<envs>
<env name="NODE_OPTIONS" value="--no-deprecation" />
</envs>
<configuration default="false" name="Run Dev _community" type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="dev" />
</scripts>
<arguments value="_community" />
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>

View File

@@ -0,0 +1,13 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Dev admin" type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="dev" />
</scripts>
<arguments value="admin" />
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>

View File

@@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="true" type="JavaScriptTestRunnerJest">
<node-interpreter value="project" />
<node-options value="--experimental-vm-modules --no-deprecation" />
<node-options value="--no-deprecation" />
<envs />
<scope-kind value="ALL" />
<method v="2" />

3
.npmrc
View File

@@ -1,2 +1,3 @@
symlink=true
node-linker=isolated # due to a typescript bug, isolated mode requires @types/express-serve-static-core, terser and monaco-editor to be installed https://github.com/microsoft/TypeScript/issues/47663#issuecomment-1519138189 along with two other changes in the code which I've marked with (tsbugisolatedmode) in the code
node-linker=isolated
hoist-workspace-packages=false # the default in pnpm v9 is true, but that can break our runtime dependency checks

14
.vscode/launch.json vendored
View File

@@ -56,6 +56,20 @@
"request": "launch",
"type": "node-terminal"
},
{
"command": "node --no-deprecation test/dev.js fields-relationship",
"cwd": "${workspaceFolder}",
"name": "Run Dev Fields-Relationship",
"request": "launch",
"type": "node-terminal"
},
{
"command": "node --no-deprecation test/dev.js login-with-username",
"cwd": "${workspaceFolder}",
"name": "Run Dev Login-With-Username",
"request": "launch",
"type": "node-terminal"
},
{
"command": "pnpm run dev plugin-cloud-storage",
"cwd": "${workspaceFolder}",

View File

@@ -42,8 +42,8 @@
}
},
"files.insertFinalNewline": true,
"jestrunner.jestCommand": "pnpm exec cross-env NODE_OPTIONS=\"--experimental-vm-modules --no-deprecation\" node 'node_modules/jest/bin/jest.js'",
"jestrunner.jestCommand": "pnpm exec cross-env NODE_OPTIONS=\"--no-deprecation\" node 'node_modules/jest/bin/jest.js'",
"jestrunner.debugOptions": {
"runtimeArgs": ["--experimental-vm-modules", "--no-deprecation"]
"runtimeArgs": ["--no-deprecation"]
}
}

View File

@@ -63,7 +63,7 @@ Each test directory is split up in this way specifically to reduce friction when
The following command will start Payload with your config: `pnpm dev my-test-dir`. Example: `pnpm dev fields` for the test/`fields` test suite. This command will start up Payload using your config and refresh a test database on every restart. If you're using VS Code, the most common run configs are automatically added to your editor - you should be able to find them in your VS Code launch tab.
By default, payload will [automatically log you in](https://payloadcms.com/docs/authentication/config#admin-autologin) with the default credentials. To disable that, you can either pass in the --no-auto-login flag (example: `pnpm dev my-test-dir --no-auto-login`) or set the `PAYLOAD_PUBLIC_DISABLE_AUTO_LOGIN` environment variable to `false`.
By default, payload will [automatically log you in](https://payloadcms.com/docs/authentication/overview#admin-autologin) with the default credentials. To disable that, you can either pass in the --no-auto-login flag (example: `pnpm dev my-test-dir --no-auto-login`) or set the `PAYLOAD_PUBLIC_DISABLE_AUTO_LOGIN` environment variable to `false`.
The default credentials are `dev@payloadcms.com` as E-Mail and `test` as password. These are used in the auto-login.
@@ -120,5 +120,5 @@ This is how you can preview changes you made locally to the docs:
2. Run `yarn install`
3. Duplicate the `.env.example` file and rename it to `.env`
4. Add a `DOCS_DIR` environment variable to the `.env` file which points to the absolute path of your modified docs folder. For example `DOCS_DIR=/Users/yourname/Documents/GitHub/payload/docs`
5. Run `yarn run fetchDocs:local`. If this was successful, you should see no error messages and the following output: *Docs successfully written to /.../website/src/app/docs.json*. There could be error messages if you have incorrect markdown in your local docs folder. In this case, it will tell you how you can fix it
5. Run `yarn run fetchDocs:local`. If this was successful, you should see no error messages and the following output: _Docs successfully written to /.../website/src/app/docs.json_. There could be error messages if you have incorrect markdown in your local docs folder. In this case, it will tell you how you can fix it
6. You're done! Now you can start the website locally using `yarn run dev` and preview the docs under [http://localhost:3000/docs/](http://localhost:3000/docs/)

14
app/(app)/layout.tsx Normal file
View File

@@ -0,0 +1,14 @@
import React from 'react'
export const metadata = {
description: 'Generated by Next.js',
title: 'Next.js',
}
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}

11
app/(app)/test/page.tsx Normal file
View File

@@ -0,0 +1,11 @@
import configPromise from '@payload-config'
import { getPayloadHMR } from '@payloadcms/next/utilities'
export const Page = async ({ params, searchParams }) => {
const payload = await getPayloadHMR({
config: configPromise,
})
return <div>test ${payload?.config?.collections?.length}</div>
}
export default Page

View File

@@ -5,6 +5,8 @@ import config from '@payload-config'
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import { NotFoundPage, generatePageMetadata } from '@payloadcms/next/views'
import { importMap } from '../importMap.js'
type Args = {
params: {
segments: string[]
@@ -17,6 +19,7 @@ type Args = {
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
generatePageMetadata({ config, params, searchParams })
const NotFound = ({ params, searchParams }: Args) => NotFoundPage({ config, params, searchParams })
const NotFound = ({ params, searchParams }: Args) =>
NotFoundPage({ config, importMap, params, searchParams })
export default NotFound

View File

@@ -5,6 +5,8 @@ import config from '@payload-config'
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import { RootPage, generatePageMetadata } from '@payloadcms/next/views'
import { importMap } from '../importMap.js'
type Args = {
params: {
segments: string[]
@@ -17,6 +19,7 @@ type Args = {
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
generatePageMetadata({ config, params, searchParams })
const Page = ({ params, searchParams }: Args) => RootPage({ config, params, searchParams })
const Page = ({ params, searchParams }: Args) =>
RootPage({ config, importMap, params, searchParams })
export default Page

View File

@@ -1,6 +1,9 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
import configPromise from '@payload-config'
import { RootLayout } from '@payloadcms/next/layouts'
import { importMap } from './admin/importMap.js'
// import '@payloadcms/ui/styles.css' // Uncomment this line if `@payloadcms/ui` in `tsconfig.json` points to `/ui/dist` instead of `/ui/src`
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import React from 'react'
@@ -11,6 +14,10 @@ type Args = {
children: React.ReactNode
}
const Layout = ({ children }: Args) => <RootLayout config={configPromise}>{children}</RootLayout>
const Layout = ({ children }: Args) => (
<RootLayout config={configPromise} importMap={importMap}>
{children}
</RootLayout>
)
export default Layout

View File

@@ -44,7 +44,7 @@ export const CollectionWithAccessControl: CollectionConfig = {
unlock: () => {...},
// Version-enabled Collections only
readVersion: () => {...},
readVersions: () => {...},
},
// highlight-end
}
@@ -286,7 +286,7 @@ The following arguments are provided to the `admin` function:
### Unlock
Determines which users can [unlock](/docs/authentication/operations#unlock) other users who may be blocked from authenticating successfully due to [failing too many login attempts](/docs/authentication/config#options).
Determines which users can [unlock](/docs/authentication/operations#unlock) other users who may be blocked from authenticating successfully due to [failing too many login attempts](/docs/authentication/overview#options).
To add Unlock Access Control to a Collection, use the `unlock` property in the [Collection Config](../collections/overview):

View File

@@ -46,7 +46,7 @@ const defaultPayloadAccess = ({ req: { user } }) => {
In the [Local API](../local-api/overview), all Access Control is _skipped_ by default. This allows your server to have full control over your application. To opt back in, you can set the `overrideAccess` option to `false` in your requests.
</Banner>
## The Admin Panel
## The Access Operation
The Admin Panel responds dynamically to your changes to Access Control. For example, if you restrict editing `ExampleCollection` to only users that feature an "admin" role, Payload will **hide** that Collection from the Admin Panel entirely. This is super powerful and allows you to control who can do what within your Admin Panel using the same functions that secure your APIs.

173
docs/admin/collections.mdx Normal file
View File

@@ -0,0 +1,173 @@
---
title: Collection Admin Config
label: Collections
order: 20
desc:
keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
The behavior of [Collections](../configuration/collections) within the [Admin Panel](./overview) can be fully customized to fit the needs of your application. This includes grouping or hiding their navigation links, adding [Custom Components](./components), selecting which fields to display in the List View, and more.
To configure Admin Options for Collections, use the `admin` property in your Collection Config:
```ts
import { CollectionConfig } from 'payload'
export const MyCollection: CollectionConfig = {
// ...
admin: { // highlight-line
// ...
},
}
```
## Admin Options
The following options are available:
| Option | Description |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`group`** | Text used as a label for grouping Collection and Global links together in the navigation. |
| **`hidden`** | Set to true or a function, called with the current user, returning true to exclude this Collection from navigation and admin routing. |
| **`hooks`** | Admin-specific hooks for this Collection. [More details](../hooks/collections). |
| **`useAsTitle`** | Specify a top-level field to use for a document title throughout the Admin Panel. If no field is defined, the ID of the document is used as the title. |
| **`description`** | Text to display below the Collection label in the List View to give editors more information. Alternatively, you can use the `admin.components.Description` to render a React component. [More details](#components). |
| **`defaultColumns`** | Array of field names that correspond to which columns to show by default in this Collection's List View. |
| **`hideAPIURL`** | Hides the "API URL" meta field while editing documents within this Collection. |
| **`enableRichTextLink`** | The [Rich Text](../fields/rich-text) field features a `Link` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
| **`enableRichTextRelationship`** | The [Rich Text](../fields/rich-text) field features a `Relationship` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
| **`meta`** | Page metadata overrides to apply to this Collection within the Admin Panel. [More details](./metadata). |
| **`preview`** | Function to generate preview URLs within the Admin Panel that can point to your app. [More details](#preview). |
| **`livePreview`** | Enable real-time editing for instant visual feedback of your front-end application. [More details](../live-preview/overview). |
| **`components`** | Swap in your own React components to be used within this Collection. [More details](#components). |
| **`listSearchableFields`** | Specify which fields should be searched in the List search view. [More details](#list-searchable-fields). |
| **`pagination`** | Set pagination-specific options for this Collection. [More details](#pagination). |
### Components
Collections can set their own [Custom Components](./components) which only apply to [Collection](../configuration/collections)-specific UI within the [Admin Panel](./overview). This includes elements such as the Save Button, or entire layouts such as the Edit View.
To override Collection Components, use the `admin.components` property in your [Collection Config](../configuration/collections):
```ts
import type { SanitizedCollectionConfig } from 'payload'
export const MyCollection: SanitizedCollectionConfig = {
// ...
admin: {
components: { // highlight-line
// ...
},
},
}
```
The following options are available:
| Path | Description |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **`beforeList`** | An array of components to inject _before_ the built-in List View |
| **`beforeListTable`** | An array of components to inject _before_ the built-in List View's table |
| **`afterList`** | An array of components to inject _after_ the built-in List View |
| **`afterListTable`** | An array of components to inject _after_ the built-in List View's table
| **`Description`** | A component to render below the Collection label in the List View. An alternative to the `admin.description` property. |
| **`edit.SaveButton`** | Replace the default Save Button with a Custom Component. [Drafts](../versions/drafts) must be disabled. |
| **`edit.SaveDraftButton`** | Replace the default Save Draft Button with a Custom Component. [Drafts](../versions/drafts) must be enabled and autosave must be disabled. |
| **`edit.PublishButton`** | Replace the default Publish Button with a Custom Component. [Drafts](../versions/drafts) must be enabled. |
| **`edit.PreviewButton`** | Replace the default Preview Button with a Custom Component. [Preview](#preview) must be enabled. |
| **`views`** | Override or create new views within the Admin Panel. [More details](./views). |
<Banner type="success">
<strong>Note:</strong>
For details on how to build Custom Components, see [Building Custom Components](./components#building-custom-components).
</Banner>
### Preview
It is possible to display a Preview Button within the Edit View of the Admin Panel. This will allow editors to visit the frontend of your app the corresponds to the document they are actively editing. This way they can preview the latest, potentially unpublished changes.
To configure the Preview Button, set the `admin.preview` property to a function in your [Collection Config](../configuration/collections):
```ts
import { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
admin: {
// highlight-start
preview: (doc, { locale }) => {
if (doc?.slug) {
return `/${doc.slug}?locale=${locale}`
}
return null
},
// highlight-end
},
}
```
The preview function receives two arguments:
| Argument | Description |
| --- | --- |
| **`doc`** | The Document being edited. |
| **`ctx`** | An object containing `locale` and `token` properties. The `token` is the currently logged-in user's JWT. |
<Banner type="success">
<strong>Note:</strong>
For fully working example of this, check of the official [Draft Preview Example](https://github.com/payloadcms/payload/tree/main/examples/draft-preview) in the [Examples Directory](https://github.com/payloadcms/payload/tree/main/examples).
</Banner>
### Pagination
All Collections receive their own List View which displays a paginated list of documents that can be sorted and filtered. The pagination behavior of the List View can be customized on a per-Collection basis, and uses the same [Pagination](../queries/pagination) API that Payload provides.
To configure pagination options, use the `admin.pagination` property in your [Collection Config](../configuration/collections):
```ts
import { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
admin: {
// highlight-start
pagination: {
defaultLimit: 10,
limits: [10, 20, 50],
},
// highlight-end
},
}
```
The following options are available:
| Option | Description |
| -------------- | --------------------------------------------------------------------------------------------------- |
| `defaultLimit` | Integer that specifies the default per-page limit that should be used. Defaults to 10. |
| `limits` | Provide an array of integers to use as per-page options for admins to choose from in the List View. |
### List Searchable Fields
In the List View, there is a "search" box that allows you to quickly find a document through a simple text search. By default, it searches on the ID field. If defined, the `admin.useAsTitle` field is used. Or, you can explicitly define which fields to search based on the needs of your application.
To define which fields should be searched, use the `admin.listSearchableFields` property in your [Collection Config](../configuration/collections):
```ts
import { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
admin: {
// highlight-start
listSearchableFields: ['title', 'slug'],
// highlight-end
},
}
```
<Banner type="warning">
<strong>Tip:</strong>
If you are adding `listSearchableFields`, make sure you index each of these fields so your admin queries can remain performant.
</Banner>

View File

@@ -1,7 +1,7 @@
---
title: Swap in your own React components
label: Custom Components
order: 20
order: 40
desc: Fully customize your Admin Panel by swapping in your own React components. Add fields, remove views, update routes and change functions to sculpt your perfect Dashboard.
keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
@@ -18,12 +18,184 @@ All Custom Components in Payload are [React Server Components](https://react.dev
There are four main types of Custom Components in Payload:
- [Root Components](#root-components)
- [Collection Components](#collection-components)
- [Global Components](#global-components)
- [Collection Components](./collections#components)
- [Global Components](./globals#components)
- [Field Components](./fields)
To swap in your own Custom Component, consult the list of available components. Determine the scope that corresponds to what you are trying to accomplish, then [author your React component(s)](#building-custom-components) accordingly.
## Defining Custom Components in the Payload Config
In the Payload Config, you can define custom React Components to enhance the admin interface. However, these components should not be imported directly into the server-only Payload Config to avoid including client-side code. Instead, you specify the path to the component. Heres how you can do it:
src/components/Logout.tsx
```tsx
'use client'
import React from 'react'
export const MyComponent = () => {
return (
<button>Click me!</button>
)
}
```
payload.config.ts:
```ts
import { buildConfig } from 'payload'
const config = buildConfig({
// ...
admin: { // highlight-line
components: {
logout: {
Button: '/src/components/Logout#MyComponent'
}
}
},
})
```
In the path `/src/components/Logout#MyComponent`, `/src/components/Logout` is the file path, and `MyComponent` is the named export. If the component is the default export, the export name can be omitted. Path and export name are separated by a `#`.
### Configuring the Base Directory
Component paths, by default, are relative to your working directory - this is usually where your Next.js config lies. To simplify component paths, you have the option to configure the *base directory* using the `admin.baseDir.baseDir` property:
```ts
import { buildConfig } from 'payload'
import { fileURLToPath } from 'node:url'
import path from 'path'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
const config = buildConfig({
// ...
admin: { // highlight-line
importMap: {
baseDir: path.resolve(dirname, 'src'),
},
components: {
logout: {
Button: '/components/Logout#MyComponent'
}
}
},
})
```
In this example, we set the base directory to the `src` directory - thus we can omit the `/src/` part of our component path string.
### Passing Props
Each React Component in the Payload Config is typed as `PayloadComponent`. This usually is a string, but can also be an object containing the following properties:
| Property | Description |
|---------------|-------------------------------------------------------------------------------------------------------------------------------|
| `clientProps` | Props to be passed to the React Component if it's a Client Component |
| `exportName` | Instead of declaring named exports using `#` in the component path, you can also omit them from `path` and pass them in here. |
| `path` | Path to the React Component. Named exports can be appended to the end of the path, separated by a `#` |
| `serverProps` | Props to be passed to the React Component if it's a Server Component |
To pass in props from the config, you can use the `clientProps` and/or `serverProps` properties. This alleviates the need to use an HOC (Higher-Order-Component) to declare a React Component with props passed in.
Here is an example:
src/components/Logout.tsx
```tsx
'use client'
import React from 'react'
export const MyComponent = ({ text }: { text: string }) => {
return (
<button>Click me! {text}</button>
)
}
```
payload.config.ts:
```ts
import { buildConfig } from 'payload'
const config = buildConfig({
// ...
admin: { // highlight-line
components: {
logout: {
Button: {
path: '/src/components/Logout',
clientProps: {
text: 'Some Text.'
},
exportName: 'MyComponent'
}
}
}
},
})
```
### Import Maps
It's essential to understand how `PayloadComponent` paths function behind the scenes. Directly importing React Components into your Payload Config using import statements can introduce client-only modules like CSS into your server-only config. This could error when attempting to load the Payload Config in server-only environments and unnecessarily increase the size of the Payload Config, which should remain streamlined and efficient for server use.
Instead, we utilize component paths to reference React Components. This method enhances the Payload Config with actual React Component imports on the client side, without affecting server-side usage. A script is deployed to scan the Payload Config, collecting all component paths and creating an `importMap.js`. This file, located in app/(payload)/admin/importMap.js, must be statically imported by your Next.js root page and layout. The script imports all the React Components from the specified paths into a Map, associating them with their respective paths (the ones you defined).
When constructing the `ClientConfig`, Payload uses the component paths as keys to fetch the corresponding React Component imports from the Import Map. It then substitutes the `PayloadComponent` with a `MappedComponent`. A `MappedComponent` includes the React Component and additional metadata, such as whether it's a server or a client component and which props it should receive. These components are then rendered through the `<RenderComponent />` component within the Payload Admin Panel.
Import maps are regenerated whenever you modify any element related to component paths. This regeneration occurs at startup and whenever Hot Module Replacement (HMR) runs. If the import maps fail to regenerate during HMR, you can restart your application and execute the `payload generate:importmap` command to manually create a new import map. If you encounter any errors running this command, see the [Troubleshooting](/docs/beta/local-api/outside-nextjs#troubleshooting) section.
### Component paths in external packages
Component paths are resolved relative to your project's base directory, which is either your current working directory or the directory specified in `config.admin.baseDir`. When using custom components from external packages, you can't use relative paths. Instead, use an import path that's accessible as if you were writing an import statement in your project's base directory.
For example, to export a field with a custom component from an external package named `my-external-package`:
```ts
import type { Field } from 'payload'
export const MyCustomField: Field = {
type: 'text',
name: 'MyField',
admin: {
components: {
Field: 'my-external-package/client#MyFieldComponent'
}
}
}
```
Despite `MyFieldComponent` living in `src/components/MyFieldComponent.tsx` in `my-external-package`, this will not be accessible from the consuming project. Instead, we recommend exporting all custom components from one file in the external package. For example, you can define a `src/client.ts file in `my-external-package`:
```ts
'use client'
export { MyFieldComponent } from './components/MyFieldComponent'
```
Then, update the package.json of `my-external-package:
```json
{
...
"exports": {
"./client": {
"import": "./dist/client.js",
"types": "./dist/client.d.ts",
"default": "./dist/client.js"
}
}
}
```
This setup allows you to specify the component path as `my-external-package/client#MyFieldComponent` as seen above. The import map will generate:
```ts
import { MyFieldComponent } from 'my-external-package/client'
```
which is a valid way to access MyFieldComponent that can be resolved by the consuming project.
## Root Components
Root Components are those that effect the [Admin Panel](./overview) generally, such as the logo or the main nav.
@@ -33,16 +205,14 @@ To override Root Components, use the `admin.components` property in your [Payloa
```ts
import { buildConfig } from 'payload'
import { MyCustomLogo } from './MyCustomLogo'
export default buildConfig({
// ...
admin: {
// highlight-start
components: {
graphics: {
Logo: MyCustomLogo, // highlight-line
},
// ...
},
// highlight-end
},
})
```
@@ -63,30 +233,29 @@ The following options are available:
| **`logout.Button`** | The button displayed in the sidebar that logs the user out. |
| **`graphics.Icon`** | The simplified logo used in contexts like the the `Nav` component. |
| **`graphics.Logo`** | The full logo used in contexts like the `Login` view. |
| **`providers`** | Custom [React Context](https://react.dev/learn/scaling-up-with-reducer-and-context) providers that will wrap the entire [Admin Panel](./overview). [More details](#custom-providers). |
| **`actions`** | An array of Custom Components to be rendered in the header of the [Admin Panel](./overview), providing additional interactivity and functionality. |
| **`views`** | Override or create new views within the [Admin Panel](./overview). [More details](./views). |
| **`providers`** | Custom [React Context](https://react.dev/learn/scaling-up-with-reducer-and-context) providers that will wrap the entire Admin Panel. [More details](#custom-providers). |
| **`actions`** | An array of Custom Components to be rendered in the header of the Admin Panel, providing additional interactivity and functionality. |
| **`views`** | Override or create new views within the Admin Panel. [More details](./views). |
<Banner type="success">
<strong>Note:</strong> You can also use the `admin.components` property in your _[Collection](#collection-components) or [Global](#global-components)_.
<strong>Note:</strong>
You can also use set [Collection Components](./collections#components) and [Global Components](./globals#components) in their respective configs.
</Banner>
### Custom Providers
As you add more and more Custom Components to your [Admin Panel](./overview), you may find it helpful to add additional [React Context](https://react.dev/learn/scaling-up-with-reducer-and-context)(s). Payload allows you to inject your own context providers in your app where you can export your own custom hooks, etc.
As you add more and more Custom Components to your [Admin Panel](./overview), you may find it helpful to add additional [React Context](https://react.dev/learn/scaling-up-with-reducer-and-context)(s). Payload allows you to inject your own context providers in your app so you can export your own custom hooks, etc.
To add a Custom Provider, use the `admin.components.providers` property in your [Payload Config](../getting-started/overview):
```ts
import { buildConfig } from 'payload'
import { MyProvider } from './MyProvider'
export default buildConfig({
// ...
admin: {
components: {
providers: [MyProvider], // highlight-line
providers: ['/path/to/MyProvider'], // highlight-line
},
},
})
@@ -115,80 +284,6 @@ export const useMyCustomContext = () => useContext(MyCustomContext)
<strong>Reminder:</strong> Custom Providers are by definition Client Components. This means they must include the `use client` directive at the top of their files and cannot use server-only code.
</Banner>
## Collection Components
Collection Components are those that effect [Collection](../configuration/collections)-specific UI within the [Admin Panel](./overview), such as the save button or the List View.
To override Collection Components, use the `admin.components` property in your [Collection Config](../configuration/collections):
```ts
import type { SanitizedCollectionConfig } from 'payload'
import { CustomSaveButton } from './CustomSaveButton'
export const MyCollection: SanitizedCollectionConfig = {
slug: 'my-collection',
admin: {
components: {
edit: {
SaveButton: CustomSaveButton, // highlight-line
},
},
},
// ...
}
```
_For details on how to build Custom Components, see [Building Custom Components](#building-custom-components)._
The following options are available:
| Path | Description |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **`beforeList`** | An array of components to inject _before_ the built-in List View |
| **`beforeListTable`** | An array of components to inject _before_ the built-in List View's table |
| **`afterList`** | An array of components to inject _after_ the built-in List View |
| **`afterListTable`** | An array of components to inject _after_ the built-in List View's table |
| **`edit.SaveButton`** | Replace the default `Save` button with a Custom Component. Drafts must be disabled |
| **`edit.SaveDraftButton`** | Replace the default `Save Draft` button with a Custom Component. Drafts must be enabled and autosave must be disabled. |
| **`edit.PublishButton`** | Replace the default `Publish` button with a Custom Component. Drafts must be enabled. |
| **`edit.PreviewButton`** | Replace the default `Preview` button with a Custom Component. |
| **`views`** | Override or create new views within the [Admin Panel](./overview). [More details](./views). |
## Global Components
Global Components are those that effect [Global](../configuration/globals)-specific UI within the [Admin Panel](./overview), such as the save button or the Edit View.
To override Global Components, use the `admin.components` property in your [Global Config](../configuration/globals):
```ts
import type { SanitizedGlobalConfig } from 'payload'
import { CustomSaveButton } from './CustomSaveButton'
export const MyGlobal: SanitizedGlobalConfig = {
slug: 'my-global',
admin: {
components: {
elements: {
SaveButton: CustomSaveButton, // highlight-line
},
},
},
// ...
}
```
_For details on how to build Custom Components, see [Building Custom Components](#building-custom-components)._
The following options are available:
| Path | Description |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| **`elements.SaveButton`** | Replace the default `Save` button with a Custom Component. Drafts must be disabled. |
| **`elements.SaveDraftButton`** | Replace the default `Save Draft` button with a Custom Component. Drafts must be enabled and autosave must be disabled. |
| **`elements.PublishButton`** | Replace the default `Publish` button with a Custom Component. Drafts must be enabled. |
| **`elements.PreviewButton`** | Replace the default `Preview` button with a Custom Component. |
| **`views`** | Override or create new views within the [Admin Panel](./overview). [More details](./views). |
## Building Custom Components
All Custom Components in Payload are [React Server Components](https://react.dev/reference/rsc/server-components) by default, with the exception of [Custom Providers](#custom-providers). This enables the use of the [Local API](../local-api) directly on the front-end, among other things.
@@ -280,7 +375,7 @@ import React from 'react'
import { useConfig } from '@payloadcms/ui'
export const MyClientComponent: React.FC = () => {
const { serverURL } = useConfig() // highlight-line
const { config: { serverURL } } = useConfig() // highlight-line
return (
<Link href={serverURL}>
@@ -294,6 +389,22 @@ export const MyClientComponent: React.FC = () => {
See [Using Hooks](#using-hooks) for more details.
</Banner>
All [Field Components](./fields) automatically receive their respective Client Field Config through a common [`field`](./fields#the-field-prop) prop:
```tsx
'use client'
import React from 'react'
import type { TextFieldProps } from 'payload'
export const MyClientFieldComponent: TextFieldProps = ({ field: { name } }) => {
return (
<p>
{`This field's name is ${name}`}
</p>
)
}
```
### Using Hooks
To make it easier to [build your Custom Components](#building-custom-components), you can use [Payload's built-in React Hooks](./hooks) in any Client Component. For example, you might want to interact with one of Payload's many React Contexts:

View File

@@ -1,7 +1,7 @@
---
title: Customizing CSS & SCSS
label: Customizing CSS
order: 60
order: 80
desc: Customize the Payload Admin Panel further by adding your own CSS or SCSS style sheet to the configuration, powerful theme and design options are waiting for you.
keywords: admin, css, scss, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---

View File

@@ -1,7 +1,7 @@
---
title: Customizing Fields
label: Customizing Fields
order: 40
order: 60
desc:
keywords:
---
@@ -18,7 +18,7 @@ For example, your app might need to render a specific interface that Payload doe
## Admin Options
You can customize the appearance and behavior of fields within the [Admin Panel](./overvieW) through the `admin` property of any [Field Config](../fields/overview):
You can customize the appearance and behavior of fields within the [Admin Panel](./overview) through the `admin` property of any [Field Config](../fields/overview):
```ts
import type { CollectionConfig } from 'payload'
@@ -117,7 +117,7 @@ export const CollectionConfig: CollectionConfig = {
// ...
admin: {
components: {
Field: MyFieldComponent, // highlight-line
Field: '/path/to/MyFieldComponent', // highlight-line
},
},
}
@@ -135,32 +135,12 @@ All Field Components receive the following props:
| Property | Description |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`AfterInput`** | The rendered result of the `admin.components.afterInput` property. [More details](#afterinput-and-beforeinput). |
| **`BeforeInput`** | The rendered result of the `admin.components.beforeInput` property. [More details](#afterinput-and-beforeinput). |
| **`CustomDescription`** | The rendered result of the `admin.components.Description` property. [More details](#the-description-component). |
| **`CustomError`** | The rendered result of the `admin.components.Error` property. [More details](#the-error-component). |
| **`CustomLabel`** | The rendered result of the `admin.components.Label` property. [More details](#the-label-component).
| **`path`** | The static path of the field at render time. [More details](./hooks#usefieldprops). |
| **`disabled`** | The `admin.disabled` property defined in the [Field Config](../fields/overview). |
| **`required`** | The `admin.required` property defined in the [Field Config](../fields/overview). |
| **`className`** | The `admin.className` property defined in the [Field Config](../fields/overview). |
| **`style`** | The `admin.style` property defined in the [Field Config](../fields/overview). |
| **`custom`** | The `admin.custom` property defined in the [Field Config](../fields/overview).
| **`placeholder`** | The `admin.placeholder` property defined in the [Field Config](../fields/overview). |
| **`descriptionProps`** | An object that contains the props for the `FieldDescription` component. |
| **`labelProps`** | An object that contains the props needed for the `FieldLabel` component. |
| **`errorProps`** | An object that contains the props for the `FieldError` component. |
| **`docPreferences`** | An object that contains the preferences for the document. |
| **`label`** | The label value provided in the field, it can be used with i18n. |
| **`docPreferences`** | An object that contains the [Preferences](./preferences) for the document.
| **`field`** | The sanitized, client-friendly version of the field's config. [More details](#the-field-prop) |
| **`locale`** | The locale of the field. [More details](../configuration/localization). |
| **`localized`** | A boolean value that represents if the field is localized or not. [More details](../fields/localized). |
| **`readOnly`** | A boolean value that represents if the field is read-only or not. |
| **`rtl`** | A boolean value that represents if the field should be rendered right-to-left or not. [More details](../configuration/i18n). |
| **`user`** | The currently authenticated user. [More details](../authentication/overview). |
| **`validate`** | A function that can be used to validate the field. |
| **`hasMany`** | If a [`relationship`](../fields/relationship) field, the `hasMany` property defined in the [Field Config](../fields/overview). |
| **`maxLength`** | If a [`text`](../fields/text) field, the `maxLength` property defined in the [Field Config](../fields/overview). |
| **`minLength`** | If a [`text`](../fields/text) field, the `minLength` property defined in the [Field Config](../fields/overview). |
<Banner type="success">
<strong>Reminder:</strong>
@@ -193,6 +173,105 @@ export const CustomTextField: React.FC = () => {
For a complete list of all available React hooks, see the [Payload React Hooks](./hooks) documentation. For additional help, see [Building Custom Components](./components#building-custom-components).
</Banner>
#### TypeScript
When building Custom Field Components, you can import the component props to ensure type safety in your component. There is an explicit type for the Field Component, one for every [Field Type](../fields/overview). The convention is to append `Props` to the type of field, i.e. `TextFieldProps`.
```tsx
import type {
ArrayFieldProps,
BlocksFieldProps,
CheckboxFieldProps,
CodeFieldProps,
CollapsibleFieldProps,
DateFieldProps,
EmailFieldProps,
GroupFieldProps,
HiddenFieldProps,
JSONFieldProps,
NumberFieldProps,
PointFieldProps,
RadioFieldProps,
RelationshipFieldProps,
RichTextFieldProps,
RowFieldProps,
SelectFieldProps,
TabsFieldProps,
TextFieldProps,
TextareaFieldProps,
UploadFieldProps
} from 'payload'
```
### The `field` Prop
All Field Components are passed a client-friendly version of their Field Config through a common `field` prop. Since the raw Field Config is [non-serializable](https://react.dev/reference/rsc/use-client#serializable-types), Payload sanitized it into a [Client Config](./components#accessing-the-payload-config) that is safe to pass into Client Components.
The exact shape of this prop is unique to the specific [Field Type](../fields/overview) being rendered, minus all non-serializable properties. Any [Custom Components](../components) are also resolved into a "mapped component" that is safe to pass.
```tsx
'use client'
import React from 'react'
import type { TextFieldProps } from 'payload'
export const MyClientFieldComponent: React.FC<TextFieldProps> = ({ field: { name } }) => {
return (
<p>
{`This field's name is ${name}`}
</p>
)
}
```
The following additional properties are also provided to the `field` prop:
| Property | Description |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`_isPresentational`** | A boolean indicating that the field is purely visual and does not directly affect data or change data shape, i.e. the [UI Field](../fields/ui). |
| **`_path`** | A string representing the direct, dynamic path to the field at runtime, i.e. `myGroup.myArray[0].myField`. |
| **`_schemaPath`** | A string representing the direct, static path to the [Field Config](../fields/overview), i.e. `myGroup.myArray.myField` |
<Banner type="info">
<strong>Note:</strong>
These properties are underscored to denote that they are not part of the original Field Config, and instead are attached during client sanitization to make fields easier to work with on the front-end.
</Banner>
#### TypeScript
When building Custom Field Components, you can import the client field props to ensure type safety in your component. There is an explicit type for the Field Component, one for every [Field Type](../fields/overview). The convention is to append `Client` to the type of field, i.e. `TextFieldClient`.
```tsx
import type {
ArrayFieldClient,
BlocksFieldClient,
CheckboxFieldClient,
CodeFieldClient,
CollapsibleFieldClient,
DateFieldClient,
EmailFieldClient,
GroupFieldClient,
HiddenFieldClient,
JSONFieldClient,
NumberFieldClient,
PointFieldClient,
RadioFieldClient,
RelationshipFieldClient,
RichTextFieldClient,
RowFieldClient,
SelectFieldClient,
TabsFieldClient,
TextFieldClient,
TextareaFieldClient,
UploadFieldClient
} from 'payload'
```
When working on the client, you will never have access to objects of type `Field`. This is reserved for the server-side. Instead, you can use `ClientField` which is a union type of all the client fields:
```tsx
import type { ClientField } from 'payload'
```
### The Cell Component
The Cell Component is rendered in the table of the List View. It represents the value of the field when displayed in a table cell.
@@ -207,7 +286,7 @@ export const myField: Field = {
type: 'text',
admin: {
components: {
Cell: MyCustomCell, // highlight-line
Cell: '/path/to/MyCustomCellComponent', // highlight-line
},
},
}
@@ -219,20 +298,9 @@ All Cell Components receive the following props:
| Property | Description |
| ---------------- | ----------------------------------------------------------------- |
| **`name`** | The name of the field. |
| **`className`** | The `admin.className` property defined in the [Field Config](../fields/overview). |
| **`fieldType`** | The `type` property defined in the [Field Config](../fields/overview). |
| **`schemaPath`** | The path to the field in the schema. Similar to `path`, but without dynamic indices. |
| **`isFieldAffectingData`** | A boolean value that represents if the field is affecting the data or not. |
| **`label`** | The label value provided in the field, it can be used with i18n. |
| **`labels`** | An object that contains the labels for the field. |
| **`field`** | The sanitized, client-friendly version of the field's config. [More details](#the-field-prop) |
| **`link`** | A boolean representing whether this cell should be wrapped in a link. |
| **`onClick`** | A function that is called when the cell is clicked. |
| **`dateDisplayFormat`** | If a [`date`](../fields/date) field, the `admin.dateDisplayFormat` property defined in the [Field Config](../fields/overview). |
| **`options`** | If a [`select`](../fields/select) field, this is an array of options defined in the [Field Config](../fields/overview). [More details](../fields/select). |
| **`relationTo`** | If a [`relationship`](../fields/relationship). or [`upload`](../fields/upload) field, this is the collection(s) the field is related to. |
| **`richTextComponentMap`** | If a [`richText`](../fields/rich-text) field, this is an object that maps the rich text components. [More details](../fields/rich-text). |
| **`blocks`** | If a [`blocks`](../fields/blocks) field, this is an array of labels and slugs representing the blocks defined in the [Field Config](../fields/overview). [More details](../fields/blocks). |
<Banner type="info">
<strong>Tip:</strong>
@@ -258,7 +326,7 @@ export const myField: Field = {
type: 'text',
admin: {
components: {
Label: MyCustomLabel, // highlight-line
Label: '/path/to/MyCustomLabelComponent', // highlight-line
},
},
}
@@ -266,19 +334,29 @@ export const myField: Field = {
_For details on how to build Custom Components, see [Building Custom Components](./components#building-custom-components)._
All Label Components receive the following props:
Custom Label Components receive all [Field Component](#the-field-component) props, plus the following props:
| Property | Description |
| -------------- | ---------------------------------------------------------------- |
| **`label`** | Label value provided in field, it can be used with i18n. |
| **`required`** | The `admin.required` property defined in the [Field Config](../fields/overview). |
| **`schemaPath`** | The path to the field in the schema. Similar to `path`, but without dynamic indices. |
| **`field`** | The sanitized, client-friendly version of the field's config. [More details](#the-field-prop) |
<Banner type="success">
<strong>Reminder:</strong>
All [Custom Server Components](./components) receive the `payload` and `i18n` properties by default. See [Building Custom Components](./components#building-custom-components) for more details.
</Banner>
#### TypeScript
When building Custom Label Components, you can import the component props to ensure type safety in your component. There is an explicit type for the Label Component, one for every [Field Type](../fields/overview) and server/client environment. The convention is to append `LabelServerComponent` or `LabelClientComponent` to the type of field, i.e. `TextFieldLabelClientComponent`.
```tsx
import type {
TextFieldLabelServerComponent,
TextFieldLabelClientComponent,
// And so on for each Field Type
} from 'payload'
```
### The Error Component
The Error Component is rendered when a field fails validation. It is typically displayed beneath the field input in a visually-compelling style.
@@ -293,7 +371,7 @@ export const myField: Field = {
type: 'text',
admin: {
components: {
Error: MyCustomError, // highlight-line
Error: '/path/to/MyCustomErrorComponent', // highlight-line
},
},
}
@@ -301,17 +379,29 @@ export const myField: Field = {
_For details on how to build Custom Components, see [Building Custom Components](./components#building-custom-components)._
All Error Components receive the following props:
Custom Error Components receive all [Field Component](#the-field-component) props, plus the following props:
| Property | Description |
| --------------- | ------------------------------------------------------------- |
| **`path`*** | The static path of the field at render time. [More details](./hooks#usefieldprops). |
| **`field`** | The sanitized, client-friendly version of the field's config. [More details](#the-field-prop) |
<Banner type="success">
<strong>Reminder:</strong>
All [Custom Server Components](./components) receive the `payload` and `i18n` properties by default. See [Building Custom Components](./components#building-custom-components) for more details.
</Banner>
#### TypeScript
When building Custom Error Components, you can import the component props to ensure type safety in your component. There is an explicit type for the Error Component, one for every [Field Type](../fields/overview) and server/client environment. The convention is to append `ErrorServerComponent` or `ErrorClientComponent` to the type of field, i.e. `TextFieldErrorClientComponent`.
```tsx
import type {
TextFieldErrorServerComponent,
TextFieldErrorClientComponent,
// And so on for each Field Type
} from 'payload'
```
### The Description Property
Field Descriptions are used to provide additional information to the editor about a field, such as special instructions. Their placement varies from field to field, but typically are displayed with subtle style differences beneath the field inputs.
@@ -385,7 +475,6 @@ To easily add a Description Component to a field, use the `admin.components.Desc
```ts
import type { SanitizedCollectionConfig } from 'payload'
import { MyCustomDescription } from './MyCustomDescription'
export const MyCollectionConfig: SanitizedCollectionConfig = {
// ...
@@ -396,7 +485,7 @@ export const MyCollectionConfig: SanitizedCollectionConfig = {
type: 'text',
admin: {
components: {
Description: MyCustomDescription, // highlight-line
Description: '/path/to/MyCustomDescriptionComponent', // highlight-line
}
}
}
@@ -406,17 +495,29 @@ export const MyCollectionConfig: SanitizedCollectionConfig = {
_For details on how to build a Custom Description, see [Building Custom Components](./components#building-custom-components)._
All Description Components receive the following props:
Custom Description Components receive all [Field Component](#the-field-component) props, plus the following props:
| Property | Description |
| -------------- | ---------------------------------------------------------------- |
| **`description`** | The `description` property defined in the [Field Config](../fields/overview). |
| **`field`** | The sanitized, client-friendly version of the field's config. [More details](#the-field-prop) |
<Banner type="success">
<strong>Reminder:</strong>
All [Custom Server Components](./components) receive the `payload` and `i18n` properties by default. See [Building Custom Components](./components#building-custom-components) for more details.
</Banner>
#### TypeScript
When building Custom Description Components, you can import the component props to ensure type safety in your component. There is an explicit type for the Description Component, one for every [Field Type](../fields/overview) and server/client environment. The convention is to append `DescriptionServerComponent` or `DescriptionClientComponent` to the type of field, i.e. `TextFieldDescriptionClientComponent`.
```tsx
import type {
TextFieldDescriptionServerComponent,
TextFieldDescriptionClientComponent,
// And so on for each Field Type
} from 'payload'
```
### afterInput and beforeInput
With these properties you can add multiple components _before_ and _after_ the input element, as their name suggests. This is useful when you need to render additional elements alongside the field without replacing the entire field component.
@@ -436,8 +537,8 @@ export const MyCollectionConfig: SanitizedCollectionConfig = {
admin: {
components: {
// highlight-start
beforeInput: [MyCustomComponent],
afterInput: [MyOtherCustomComponent],
beforeInput: ['/path/to/MyCustomComponent'],
afterInput: ['/path/to/MyOtherCustomComponent'],
// highlight-end
}
}

107
docs/admin/globals.mdx Normal file
View File

@@ -0,0 +1,107 @@
---
title: Global Admin Config
label: Globals
order: 30
desc:
keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
The behavior of [Globals](../configuration/globals) within the [Admin Panel](./overview) can be fully customized to fit the needs of your application. This includes grouping or hiding their navigation links, adding [Custom Components](./components), setting page metadata, and more.
To configure Admin Options for Globals, use the `admin` property in your Global Config:
```ts
import { GlobalConfig } from 'payload'
export const MyGlobal: GlobalConfig = {
// ...
admin: { // highlight-line
// ...
},
}
```
## Admin Options
The following options are available:
| Option | Description |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| **`group`** | Text used as a label for grouping Collection and Global links together in the navigation. |
| **`hidden`** | Set to true or a function, called with the current user, returning true to exclude this Global from navigation and admin routing. |
| **`components`** | Swap in your own React components to be used within this Global. [More details](#components). |
| **`preview`** | Function to generate a preview URL within the Admin Panel for this Global that can point to your app. [More details](#preview). |
| **`livePreview`** | Enable real-time editing for instant visual feedback of your front-end application. [More details](../live-preview/overview). |
| **`hideAPIURL`** | Hides the "API URL" meta field while editing documents within this collection. |
| **`meta`** | Page metadata overrides to apply to this Global within the Admin Panel. [More details](./metadata). |
### Components
Globals can set their own [Custom Components](./components) which only apply to [Global](../configuration/globals)-specific UI within the [Admin Panel](./overview). This includes elements such as the Save Button, or entire layouts such as the Edit View.
To override Global Components, use the `admin.components` property in your [Global Config](../configuration/globals):
```ts
import type { SanitizedGlobalConfig } from 'payload'
export const MyGlobal: SanitizedGlobalConfig = {
// ...
admin: {
components: { // highlight-line
// ...
},
},
}
```
The following options are available:
| Path | Description |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| **`elements.SaveButton`** | Replace the default Save Button with a Custom Component. [Drafts](../versions/drafts) must be disabled. |
| **`elements.SaveDraftButton`** | Replace the default Save Draft Button with a Custom Component. [Drafts](../versions/drafts) must be enabled and autosave must be disabled. |
| **`elements.PublishButton`** | Replace the default Publish Button with a Custom Component. [Drafts](../versions/drafts) must be enabled. |
| **`elements.PreviewButton`** | Replace the default Preview Button with a Custom Component. [Preview](#preview) must be enabled. |
| **`views`** | Override or create new views within the Admin Panel. [More details](./views). |
<Banner type="success">
<strong>Note:</strong>
For details on how to build Custom Components, see [Building Custom Components](./components#building-custom-components).
</Banner>
### Preview
It is possible to display a Preview Button within the Edit View of the Admin Panel. This will allow editors to visit the frontend of your app the corresponds to the document they are actively editing. This way they can preview the latest, potentially unpublished changes.
To configure the Preview Button, set the `admin.preview` property to a function in your Global Config:
```ts
import { GlobalConfig } from 'payload'
export const MainMenu: GlobalConfig = {
// ...
admin: {
// highlight-start
preview: (doc, { locale }) => {
if (doc?.slug) {
return `/${doc.slug}?locale=${locale}`
}
return null
},
// highlight-end
},
}
```
The preview function receives two arguments:
| Argument | Description |
| --- | --- |
| **`doc`** | The Document being edited. |
| **`ctx`** | An object containing `locale` and `token` properties. The `token` is the currently logged-in user's JWT. |
<Banner type="success">
<strong>Note:</strong>
For fully working example of this, check of the official [Draft Preview Example](https://github.com/payloadcms/payload/tree/main/examples/draft-preview) in the [Examples Directory](https://github.com/payloadcms/payload/tree/main/examples).
</Banner>

View File

@@ -1,7 +1,7 @@
---
title: React Hooks
label: React Hooks
order: 50
order: 70
desc: Make use of all of the powerful React hooks that Payload provides.
keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
@@ -52,7 +52,7 @@ The `useField` hook accepts the following arguments:
The `useField` hook returns the following object:
```ts
type FieldResult<T> = {
type FieldType<T> = {
errorMessage?: string
errorPaths?: string[]
filterOptions?: FilterOptionsResult
@@ -65,7 +65,7 @@ type FieldResult<T> = {
readOnly?: boolean
rows?: Row[]
schemaPath: string
setValue: (val: unknown, disableModifyingForm?: boolean) => voi
setValue: (val: unknown, disableModifyingForm?: boolean) => void
showError: boolean
valid?: boolean
value: T
@@ -74,9 +74,9 @@ type FieldResult<T> = {
## useFieldProps
All [Custom Field Components](./fields#the-field-component) are rendered on the server, and as such, only have access to static props at render time. But, some fields can be dynamic, such as when nested in an [`array`](../fields/array) or [`blocks`](../fields/block) field. For example, items can be added, re-ordered, or deleted on-the-fly.
[Custom Field Components](./fields#the-field-component) can be rendered on the server. When using a server component as a custom field component, you can access dynamic props from within any client component rendered by your custom server component. This is done using the `useFieldProps` hook. This is important because some fields can be dynamic, such as when nested in an [`array`](../fields/array) or [`blocks`](../fields/block) field. For example, items can be added, re-ordered, or deleted on-the-fly.
For this reason, dynamic props like `path` are managed in their own React context, which can be accessed using the `useFieldProps` hook:
You can use the `useFieldProps` hooks to access dynamic props like `path`:
```tsx
'use client'
@@ -463,7 +463,7 @@ export const CustomArrayManager = () => {
name: "customArrayManager",
admin: {
components: {
Field: CustomArrayManager,
Field: '/path/to/CustomArrayManagerField',
},
},
},
@@ -560,7 +560,7 @@ export const CustomArrayManager = () => {
name: "customArrayManager",
admin: {
components: {
Field: CustomArrayManager,
Field: '/path/to/CustomArrayManagerField',
},
},
},
@@ -670,7 +670,7 @@ export const CustomArrayManager = () => {
name: "customArrayManager",
admin: {
components: {
Field: CustomArrayManager,
Field: '/path/to/CustomArrayManagerField',
},
},
},
@@ -818,7 +818,7 @@ import { useConfig } from '@payloadcms/ui'
const MyComponent: React.FC = () => {
// highlight-start
const config = useConfig()
const { config } = useConfig()
// highlight-end
return <span>{config.serverURL}</span>

216
docs/admin/metadata.mdx Normal file
View File

@@ -0,0 +1,216 @@
---
title: Page Metadata
label: Metadata
order: 70
desc: Customize the metadata of your pages within the Admin Panel
keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Every page within the Admin Panel automatically receives dynamic, auto-generated metadata derived from live document data, the user's current locale, and more, without any additional configuration. This includes the page title, description, og:image and everything in between. Metadata is fully configurable at the root level and cascades down to individual collections, documents, and custom views, allowing for the ability to control metadata on any page with high precision.
Within the Admin Panel, metadata can be customized at the following levels:
- [Root Metadata](#root-metadata)
- [Collection Metadata](#collection-metadata)
- [Global Metadata](#global-metadata)
- [View Metadata](#view-metadata)
All of these types of metadata share a similar structure, with a few key differences on the Root level. To customize metadata, consult the list of available scopes. Determine the scope that corresponds to what you are trying to accomplish, then author your metadata within the Payload Config accordingly.
## Root Metadata
Root Metadata is the metadata that is applied to all pages within the Admin Panel. This is where you can control things like the suffix appended onto each page's title, the favicon displayed in the browser's tab, and the Open Graph data that is used when sharing the Admin Panel on social media.
To customize Root Metadata, use the `admin.meta` key in your Payload Config:
```ts
{
// ...
admin: {
// highlight-start
meta: {
// highlight-end
title: 'My Admin Panel',
description: 'The best admin panel in the world',
icons: [
{
rel: 'icon',
type: 'image/png',
href: '/favicon.png',
},
],
},
},
}
```
The following options are available for Root Metadata:
| Key | Type | Description |
| --- | --- | --- |
| **`title`** | `string` | The title of the Admin Panel. |
| **`description`** | `string` | The description of the Admin Panel. |
| **`defaultOGImageType`** | `dynamic` (default), `static`, or `off` | The type of default OG image to use. If set to `dynamic`, Payload will use Next.js image generation to create an image with the title of the page. If set to `static`, Payload will use the `defaultOGImage` URL. If set to `off`, Payload will not generate an OG image. |
| **`icons`** | `IconConfig[]` | An array of icon objects. [More details](#icons) |
| **`keywords`** | `string` | A comma-separated list of keywords to include in the metadata of the Admin Panel. |
| **`openGraph`** | `OpenGraphConfig` | An object containing Open Graph metadata. [More details](#open-graph) |
| **`titleSuffix`** | `string` | A suffix to append to the end of the title of every page. Defaults to "- Payload". |
<Banner type="success">
<strong>Reminder:</strong>
These are the _root-level_ options for the Admin Panel. You can also customize [Collection Metadata](./collections), [Global Metadata](./globals), and [Document Metadata](./documents) in their respective configs.
</Banner>
### Icons
The Icons Config corresponds to the `<link>` tags that are used to specify icons for the Admin Panel. The `icons` key is an array of objects, each of which represents an individual icon. Icons are differentiated from one another by their `rel` attribute, which specifies the relationship between the document and the icon.
The most common icon type is the favicon, which is displayed in the browser tab. This is specified by the `rel` attribute `icon`. Other common icon types include `apple-touch-icon`, which is used by Apple devices when the Admin Panel is saved to the home screen, and `mask-icon`, which is used by Safari to mask the Admin Panel icon.
To customize icons, use the `icons` key within the `admin.meta` object in your Payload Config:
```ts
{
// ...
admin: {
meta: {
// highlight-start
icons: [
// highlight-end
{
rel: 'icon',
type: 'image/png',
href: '/favicon.png',
},
{
rel: 'apple-touch-icon',
type: 'image/png',
href: '/apple-touch-icon.png',
},
],
},
},
}
```
The following options are available for Icons:
| Key | Type | Description |
| --- | --- | --- |
| **`rel`** | `string` | The HTML `rel` attribute of the icon. |
| **`type`** | `string` | The MIME type of the icon. |
| **`color`** | `string` | The color of the icon. |
| **`fetchPriority`** | `string` | The [fetch priority](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/fetchPriority) of the icon. |
| **`media`** | `string` | The [media query](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries/Using_media_queries) of the icon. |
| **`sizes`** | `string` | The [sizes](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/sizes) of the icon. |
| **`url`** | `string` | The URL pointing the resource of the icon. |
### Open Graph
Open Graph metadata is a set of tags that are used to control how URLs are displayed when shared on social media platforms. Open Graph metadata is automatically generated by Payload, but can be customized at the Root level.
To customize Open Graph metadata, use the `openGraph` key within the `admin.meta` object in your Payload Config:
```ts
{
// ...
admin: {
meta: {
// highlight-start
openGraph: {
// highlight-end
description: 'The best admin panel in the world',
images: [
{
url: 'https://example.com/image.jpg',
width: 800,
height: 600,
},
],
siteName: 'Payload',
title: 'My Admin Panel',
},
},
},
}
```
The following options are available for Open Graph Metadata:
| Key | Type | Description |
| --- | --- | --- |
| **`description`** | `string` | The description of the Admin Panel. |
| **`images`** | `OGImageConfig | OGImageConfig[]` | An array of image objects. |
| **`siteName`** | `string` | The name of the site. |
| **`title`** | `string` | The title of the Admin Panel. |
## Collection Metadata
Collection Metadata is the metadata that is applied to all pages within any given Collection within the Admin Panel. This metadata is used to customize the title and description of all views within any given Collection, unless overridden by the view itself.
To customize Collection Metadata, use the `admin.meta` key within your Collection Config:
```ts
import { CollectionConfig } from 'payload'
export const MyCollection: CollectionConfig = {
// ...
admin: {
// highlight-start
meta: {
// highlight-end
title: 'My Collection',
description: 'The best collection in the world',
},
},
}
```
The Collection Meta config has the same options as the [Root Metadata](#root-metadata) config.
## Global Metadata
Global Metadata is the metadata that is applied to all pages within any given Global within the Admin Panel. This metadata is used to customize the title and description of all views within any given Global, unless overridden by the view itself.
To customize Global Metadata, use the `admin.meta` key within your Global Config:
```ts
import { GlobalConfig } from 'payload'
export const MyGlobal: GlobalConfig = {
// ...
admin: {
// highlight-start
meta: {
// highlight-end
title: 'My Global',
description: 'The best
},
},
}
```
The Global Meta config has the same options as the [Root Metadata](#root-metadata) config.
## View Metadata
View Metadata is the metadata that is applied to specific [Views](./views) within the Admin Panel. This metadata is used to customize the title and description of a specific view, overriding any metadata set at the [Root](#root-metadata), [Collection](#collection-metadata), or [Global](#global-metadata) level.
To customize View Metadata, use the `meta` key within your View Config:
```ts
{
// ...
admin: {
views: {
dashboard: {
// highlight-start
meta: {
// highlight-end
title: 'My Dashboard',
description: 'The best dashboard in the world',
}
},
},
},
}

View File

@@ -55,6 +55,11 @@ As shown above, all Payload routes are nested within the `(payload)` route group
The `admin` directory contains all the _pages_ related to the interface itself, whereas the `api` and `graphql` directories contains all the _routes_ related to the [REST API](../rest-api/overview) and [GraphQL API](../graphql/overview). All admin routes are [easily configurable](#customizing-routes) to meet your application's exact requirements.
<Banner type="warning">
<strong>Note:</strong>
If you don't use the [REST API](../rest/overview) or [GraphQL API](../graphql/overview), you can delete the [Next.js files corresponding to those routes](../admin/overview#project-structure), however, the overhead of this API is completely constrained to these endpoints, and will not slow down or affect Payload outside of the endpoints.
</Banner>
Finally, the `custom.scss` file is where you can add or override globally-oriented styles in the Admin Panel, such as modify the color palette. Customizing the look and feel through CSS alone is a powerful feature of the Admin Panel, [more on that here](./customizing-css).
All auto-generated files will contain the following comments at the top of each file:
@@ -81,23 +86,23 @@ const config = buildConfig({
The following options are available:
| Option | Description |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `user` | The `slug` of the Collection that you want to allow to login to the Admin Panel. [More details](#the-admin-user-collection). |
| `buildPath` | Specify an absolute path for where to store the built Admin bundle used in production. Defaults to `path.resolve(process.cwd(), 'build')`. |
| `meta` | Base metadata to use for the Admin Panel. Included properties are `titleSuffix`, `icons`, and `openGraph`. Can be overridden on a per Collection or per Global basis. |
| `disable` | If set to `true`, the entire Admin Panel will be disabled. |
| `dateFormat` | The date format that will be used for all dates within the Admin Panel. Any valid [date-fns](https://date-fns.org/) format pattern can be used. |
| `avatar` | Set account profile picture. Options: `gravatar`, `default` or a custom React component. |
| `autoLogin` | Used to automate admin log-in for dev and demonstration convenience. [More details](../authentication/config). |
| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More details](../live-preview/overview). |
| `components` | Component overrides that affect the entirety of the Admin Panel. [More details](./components). |
| `routes` | Replace built-in Admin Panel routes with your own custom routes. [More details](#customizing-routes). |
| `custom` | Any custom properties you wish to pass to the Admin Panel. |
| Option | Description |
|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **`avatar`** | Set account profile picture. Options: `gravatar`, `default` or a custom React component. |
| **`autoLogin`** | Used to automate log-in for dev and demonstration convenience. [More details](../authentication/overview). |
| **`buildPath`** | Specify an absolute path for where to store the built Admin bundle used in production. Defaults to `path.resolve(process.cwd(), 'build')`. |
| **`components`** | Component overrides that affect the entirety of the Admin Panel. [More details](./components). |
| **`custom`** | Any custom properties you wish to pass to the Admin Panel. |
| **`dateFormat`** | The date format that will be used for all dates within the Admin Panel. Any valid [date-fns](https://date-fns.org/) format pattern can be used. |
| **`disable`** | If set to `true`, the entire Admin Panel will be disabled. |
| **`livePreview`** | Enable real-time editing for instant visual feedback of your front-end application. [More details](../live-preview/overview). |
| **`meta`** | Base metadata to use for the Admin Panel. [More details](./metadata). |
| **`routes`** | Replace built-in Admin Panel routes with your own custom routes. [More details](#customizing-routes). |
| **`user`** | The `slug` of the Collection that you want to allow to login to the Admin Panel. [More details](#the-admin-user-collection). |
<Banner type="success">
<strong>Reminder:</strong>
These are the _root-level_ options for the Admin Panel. You can also customize the admin options for _Collections and Globals_ through their respective `admin` keys.
These are the _root-level_ options for the Admin Panel. You can also customize [Collection Admin Options](./collections) and [Global Admin Options](./globals) through their respective `admin` keys.
</Banner>
### The Admin User Collection
@@ -162,21 +167,34 @@ const config = buildConfig({
The following options are available:
| Option | Default route | Description |
| ------------------ | ----------------------- | ------------------------------------- |
| `admin` | `/admin` | The Admin Panel itself. |
| `api` | `/api` | The [REST API](../rest-api/overview) base path. |
| `graphQL` | `/graphql` | The [GraphQL API](../graphql/overview) base path. |
| `graphQLPlayground`| `/graphql-playground` | The GraphQL Playground. |
<Banner type="warning">
<strong>Warning:</strong>
Changing Root-level Routes _after_ your project was generated will also require you to manually update the corresponding directories in your project. For example, changing `routes.admin` will require you to rename the `(payload)/admin` directory in your project to match the new route. [More details](#project-structure).
</Banner>
| Option | Default route | Description |
|---------------------|-----------------------|---------------------------------------------------|
| `admin` | `/admin` | The Admin Panel itself. |
| `api` | `/api` | The [REST API](../rest-api/overview) base path. |
| `graphQL` | `/graphql` | The [GraphQL API](../graphql/overview) base path. |
| `graphQLPlayground` | `/graphql-playground` | The GraphQL Playground. |
<Banner type="success">
<strong>Tip:</strong>
You can easily add _new_ routes to the Admin Panel through the `endpoints` property of the Payload Config. See [Custom Endpoints](../rest-api/overview#custom-endpoints) for more information.
You can easily add _new_ routes to the Admin Panel through [Custom Endpoints](../rest-api/overview#custom-endpoints) and [Custom Views](./views).
</Banner>
#### Customizing Root-level Routes
You can change the Root-level Routes as needed, such as to mount the Admin Panel at the root of your application.
Changing Root-level Routes also requires a change to [Project Structure](#project-structure) to match the new route. For example, if you set `routes.admin` to `/`, you would need to completely remove the `admin` directory from the project structure:
```plaintext
app/
├─ (payload)/
├── [[...segments]]/
├──── ...
```
<Banner type="warning">
<strong>Note:</strong>
If you set Root-level Routes _before_ auto-generating the Admin Panel, your [Project Structure](#project-structure) will already be set up correctly.
</Banner>
### Admin-level Routes

View File

@@ -1,7 +1,7 @@
---
title: Managing User Preferences
label: Preferences
order: 50
order: 70
desc: Store the preferences of your users as they interact with the Admin Panel.
keywords: admin, preferences, custom, customize, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
@@ -22,7 +22,7 @@ Out of the box, Payload handles the persistence of your users' preferences in a
that is reading or setting a preference via all provided authentication methods.
</Banner>
## Use cases
## Use Cases
This API is used significantly for internal operations of the Admin Panel, as mentioned above. But, if you're building your own React components for use in the Admin Panel, you can allow users to set their own preferences in correspondence to their usage of your components. For example:

View File

@@ -1,7 +1,7 @@
---
title: Customizing Views
label: Customizing Views
order: 30
order: 50
desc:
keywords:
---
@@ -31,7 +31,9 @@ const config = buildConfig({
admin: {
components: {
views: {
Dashboard: MyCustomDashboardView, // highlight-line
dashboard: {
Component: '/path/to/MyCustomDashboardView#MyCustomDashboardViewComponent', // highlight-line
}
},
},
},
@@ -44,18 +46,19 @@ The following options are available:
| Property | Description |
| --------------- | ----------------------------------------------------------------------------- |
| **`Account`** | The Account view is used to show the currently logged in user's Account page. |
| **`Dashboard`** | The main landing page of the [Admin Panel](./overview). |
| **`account`** | The Account view is used to show the currently logged in user's Account page. |
| **`dashboard`** | The main landing page of the [Admin Panel](./overview). |
For more granular control, pass a configuration object instead. Payload exposes the following properties for each view:
| Property | Description |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`Component`** \* | Pass in the component that should be rendered when a user navigates to this route. |
| **`Component`** \* | Pass in the component path that should be rendered when a user navigates to this route. |
| **`path`** \* | Any valid URL path or array of paths that [`path-to-regexp`](https://www.npmjs.com/package/path-to-regex) understands. |
| **`exact`** | Boolean. When true, will only match if the path matches the `usePathname()` exactly. |
| **`strict`** | When true, a path that has a trailing slash will only match a `location.pathname` with a trailing slash. This has no effect when there are additional URL segments in the pathname. |
| **`sensitive`** | When true, will match if the path is case sensitive. |
| **`sensitive`** | When true, will match if the path is case sensitive.
| **`meta`** | Page metadata overrides to apply to this view within the Admin Panel. [More details](./metadata). |
_\* An asterisk denotes that a property is required._
@@ -72,9 +75,9 @@ const config = buildConfig({
components: {
views: {
// highlight-start
MyCustomView: {
myCustomView: {
// highlight-end
Component: MyCustomView,
Component: '/path/to/MyCustomView#MyCustomViewComponent',
path: '/my-custom-view',
},
},
@@ -108,7 +111,22 @@ export const MyCollectionConfig: SanitizedCollectionConfig = {
admin: {
components: {
views: {
Edit: MyCustomEditView, // highlight-line
edit: {
root: {
Component: '/path/to/MyCustomEditView', // highlight-line
}
// other options include:
// default
// versions
// version
// api
// livePreview
// [key: string]
// See "Document Views" for more details
},
list: {
Component: '/path/to/MyCustomListView',
}
},
},
},
@@ -119,15 +137,15 @@ _For details on how to build Custom Views, see [Building Custom Views](#building
<Banner type="warning">
<strong>Note:</strong>
The `Edit` property will replace the _entire_ Edit View, including the title, tabs, etc., _as well as all nested [Document Views](#document-views)_, such as the API, Live Preview, and Version views. To replace only the Edit View precisely, use the `Edit.Default` key instead.
The `root` property will replace the _entire_ Edit View, including the title, tabs, etc., _as well as all nested [Document Views](#document-views)_, such as the API, Live Preview, and Version views. To replace only the Edit View precisely, use the `edit.default` key instead.
</Banner>
The following options are available:
| Property | Description |
| ---------- | ----------------------------------------------------------------------------------------------------------------- |
| **`Edit`** | The Edit View is used to edit a single document for any given Collection. [More details](#document-views). |
| **`List`** | The List View is used to show a list of documents for any given Collection. |
| **`edit`** | The Edit View is used to edit a single document for any given Collection. [More details](#document-views). |
| **`list`** | The List View is used to show a list of documents for any given Collection. |
<Banner type="success">
<strong>Note:</strong>
@@ -148,25 +166,36 @@ export const MyGlobalConfig: SanitizedGlobalConfig = {
admin: {
components: {
views: {
Edit: MyCustomEditView, // highlight-line
edit: {
root: {
Component: '/path/to/MyCustomEditView', // highlight-line
}
// other options include:
// default
// versions
// version
// api
// livePreview
// [key: string]
},
},
},
},
})
}
```
_For details on how to build Custom Views, see [Building Custom Views](#building-custom-views)._
<Banner type="warning">
<strong>Note:</strong>
The `Edit` property will replace the _entire_ Edit View, including the title, tabs, etc., _as well as all nested [Document Views](#document-views)_, such as the API, Live Preview, and Version views. To replace only the Edit View precisely, use the `Edit.Default` key instead.
The `root` property will replace the _entire_ Edit View, including the title, tabs, etc., _as well as all nested [Document Views](#document-views)_, such as the API, Live Preview, and Version views. To replace only the Edit View precisely, use the `edit.default` key instead.
</Banner>
The following options are available:
| Property | Description |
| ---------- | ------------------------------------------------------------------- |
| **`Edit`** | The Edit View is used to edit a single document for any given Global. [More details](#document-views). |
| **`edit`** | The Edit View is used to edit a single document for any given Global. [More details](#document-views). |
<Banner type="success">
<strong>Note:</strong>
@@ -187,37 +216,38 @@ export const MyCollectionOrGlobalConfig: SanitizedCollectionConfig = {
admin: {
components: {
views: {
Edit: {
API: {
Component: MyCustomAPIView, // highlight-line
edit: {
api: {
Component: '/path/to/MyCustomAPIViewComponent', // highlight-line
},
},
},
},
},
})
}
```
_For details on how to build Custom Views, see [Building Custom Views](#building-custom-views)._
<Banner type="warning">
<strong>Note:</strong>
If you need to replace the _entire_ Edit View, including _all_ nested Document Views, use the `Edit` key itself. See [Custom Collection Views](#collection-views) or [Custom Global Views](#global-views) for more information.
If you need to replace the _entire_ Edit View, including _all_ nested Document Views, use the `root` key. See [Custom Collection Views](#collection-views) or [Custom Global Views](#global-views) for more information.
</Banner>
The following options are available:
| Property | Description |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------- |
| **`Default`** | The Default view is the primary view in which your document is edited. |
| **`Versions`** | The Versions view is used to view the version history of a single document. [More details](../versions). |
| **`Version`** | The Version view is used to view a single version of a single document for a given collection. [More details](../versions). |
| **`API`** | The API view is used to display the REST API JSON response for a given document. |
| **`LivePreview`** | The LivePreview view is used to display the Live Preview interface. [More details](../live-preview). |
| **`root`** | The Root View overrides all other nested views and routes. No document controls or tabs are rendered when this key is set. |
| **`default`** | The Default View is the primary view in which your document is edited. It is rendered within the "Edit" tab. |
| **`versions`** | The Versions View is used to navigate the version history of a single document. It is rendered within the "Versions" tab. [More details](../versions). |
| **`version`** | The Version View is used to edit a single version of a document. It is rendered within the "Version" tab. [More details](../versions). |
| **`api`** | The API View is used to display the REST API JSON response for a given document. It is rendered within the "API" tab. |
| **`livePreview`** | The LivePreview view is used to display the Live Preview interface. It is rendered within the "Live Preview" tab. [More details](../live-preview). |
### Document Tabs
Each Document View can be given a new tab in the Edit View, if desired. Tabs are highly configurable, from as simple as changing the label to swapping out the entire component, they can be modified in any way. To add or customize tabs in the Edit View, use the `Component.Tab` key:
Each Document View can be given a new tab in the Edit View, if desired. Tabs are highly configurable, from as simple as changing the label to swapping out the entire component, they can be modified in any way. To add or customize tabs in the Edit View, use the `tab` key:
```ts
import type { SanitizedCollectionConfig } from 'payload'
@@ -227,17 +257,19 @@ export const MyCollection: SanitizedCollectionConfig = {
admin: {
components: {
views: {
Edit: {
MyCustomTab: {
Component: MyCustomTab,
edit: {
myCustomTab: {
Component: '/path/to/MyCustomTab',
path: '/my-custom-tab',
Tab: MyCustomTab // highlight-line
tab: {
Component: '/path/to/MyCustomTabComponent' // highlight-line
}
},
AnotherCustomView: {
Component: AnotherCustomView,
anotherCustomTab: {
Component: '/path/to/AnotherCustomView',
path: '/another-custom-view',
// highlight-start
Tab: {
tab: {
label: 'Another Custom View',
href: '/another-custom-view',
}
@@ -261,14 +293,15 @@ Custom Views are just [Custom Components](./components) rendered at the page-lev
```ts
import type { SanitizedCollectionConfig } from 'payload'
import { MyCustomView } from './MyCustomView'
export const MyCollectionConfig: SanitizedCollectionConfig = {
// ...
admin: {
components: {
views: {
Edit: MyCustomView, // highlight-line
edit: {
Component: '/path/to/MyCustomView' // highlight-line
}
},
},
},
@@ -278,7 +311,7 @@ export const MyCollectionConfig: SanitizedCollectionConfig = {
Your Custom Views will be provided with the following props:
| Prop | Description |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| **`user`** | The currently logged in user. |
| **`locale`** | The current [Locale](../configuration/localization) of the [Admin Panel](./overview). |
| **`navGroups`** | The grouped navigation items according to `admin.group` in your [Collection Config](../collections/overview) or [Global Config](../globals/overview). |

View File

@@ -1,206 +0,0 @@
---
title: Authentication Config
label: Config
order: 20
desc: Enable and customize options in the Authentication config for features including Forgot Password, Login Attempts, API key usage and more.
keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Payload's Authentication is extremely powerful and gives you everything you need when you go to build a new app or site in a secure and responsible manner.
To enable Authentication on a collection, define an `auth` property and set it to either `true` or to an object containing the options below.
## Options
| Option | Description |
|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **`useAPIKey`** | Payload Authentication provides for API keys to be set on each user within an Authentication-enabled Collection. [More](/docs/authentication/config#api-keys) |
| **`tokenExpiration`** | How long (in seconds) to keep the user logged in. JWTs and HTTP-only cookies will both expire at the same time. |
| **`maxLoginAttempts`** | Only allow a user to attempt logging in X amount of times. Automatically locks out a user from authenticating if this limit is passed. Set to `0` to disable. |
| **`lockTime`** | Set the time (in milliseconds) that a user should be locked out if they fail authentication more times than `maxLoginAttempts` allows for. |
| **`depth`** | How many levels deep a `user` document should be populated when creating the JWT and binding the `user` to the `req`. Defaults to `0` and should only be modified if absolutely necessary, as this will affect performance. |
| **`cookies`** | Set cookie options, including `secure`, `sameSite`, and `domain`. For advanced users. |
| **`forgotPassword`** | Customize the way that the `forgotPassword` operation functions. [More](/docs/authentication/config#forgot-password) |
| **`verify`** | Set to `true` or pass an object with verification options to require users to verify by email before they are allowed to log into your app. [More](/docs/authentication/config#email-verification) |
| **`disableLocalStrategy`** | Advanced - disable Payload's built-in local auth strategy. Only use this property if you have replaced Payload's auth mechanisms with your own. |
| **`strategies`** | Advanced - an array of custom authentification strategies to extend this collection's authentication with. [More](/docs/authentication/custom-strategies) |
### Forgot Password
You can customize how the Forgot Password workflow operates with the following options on the `auth.forgotPassword` property:
**`generateEmailHTML`**
Function that accepts one argument, containing `{ req, token, user }`, that allows for overriding the HTML within emails that are sent to users attempting to reset their password. The function should return a string that supports HTML, which can be a full HTML email.
<Banner type="success">
<strong>Tip:</strong>
<br />
HTML templating can be used to create custom email templates, inline CSS automatically, and more.
You can make a reusable function that standardizes all email sent from Payload, which makes
sending custom emails more DRY. Payload doesn't ship with an HTML templating engine, so you are
free to choose your own.
</Banner>
Example:
```ts
import { CollectionConfig } from 'payload'
export const Customers: CollectionConfig = {
slug: 'customers',
auth: {
forgotPassword: {
// highlight-start
generateEmailHTML: ({ req, token, user }) => {
// Use the token provided to allow your user to reset their password
const resetPasswordURL = `https://yourfrontend.com/reset-password?token=${token}`
return `
<!doctype html>
<html>
<body>
<h1>Here is my custom email template!</h1>
<p>Hello, ${user.email}!</p>
<p>Click below to reset your password.</p>
<p>
<a href="${resetPasswordURL}">${resetPasswordURL}</a>
</p>
</body>
</html>
`
},
// highlight-end
},
},
}
```
<Banner type="warning">
<strong>Important:</strong>
<br />
If you specify a different URL to send your users to for resetting their password, such as a page
on the frontend of your app or similar, you need to handle making the call to the Payload REST or
GraphQL reset-password operation yourself on your frontend, using the token that was provided for
you. Above, it was passed via query parameter.
</Banner>
**`generateEmailSubject`**
Similarly to the above `generateEmailHTML`, you can also customize the subject of the email. The function argument are the same but you can only return a string - not HTML.
Example:
```ts
{
slug: 'customers',
auth: {
forgotPassword: {
// highlight-start
generateEmailSubject: ({ req, user }) => {
return `Hey ${user.email}, reset your password!`;
}
// highlight-end
}
}
}
```
### Email Verification
If you'd like to require email verification before a user can successfully log in, you can enable it by passing `true` or an `options` object to `auth.verify`. The following options are available:
**`generateEmailHTML`**
Function that accepts one argument, containing `{ req, token, user }`, that allows for overriding the HTML within emails that are sent to users indicating how to validate their account. The function should return a string that supports HTML, which can optionally be a full HTML email.
Example:
```ts
import { CollectionConfig } from 'payload'
export const Customers: CollectionConfig = {
slug: 'customers',
auth: {
verify: {
// highlight-start
generateEmailHTML: ({ req, token, user }) => {
// Use the token provided to allow your user to verify their account
const url = `https://yourfrontend.com/verify?token=${token}`
return `Hey ${user.email}, verify your email by clicking here: ${url}`
},
// highlight-end
},
},
}
```
<Banner type="warning">
<strong>Important:</strong>
<br />
If you specify a different URL to send your users to for email verification, such as a page on the
frontend of your app or similar, you need to handle making the call to the Payload REST or GraphQL
verification operation yourself on your frontend, using the token that was provided for you.
Above, it was passed via query parameter.
</Banner>
**`generateEmailSubject`**
Similarly to the above `generateEmailHTML`, you can also customize the subject of the email. The function argument are the same but you can only return a string - not HTML.
Example:
```ts
{
slug: 'customers',
auth: {
forgotPassword: {
// highlight-start
generateEmailSubject: ({ req, user }) => {
return `Hey ${user.email}, reset your password!`;
}
// highlight-end
}
}
}
```
### Admin autologin
For testing and demo purposes you may want to skip forcing the admin user to login in order to access the panel.
The `admin.autologin` property is used to configure the how visitors are handled when accessing the Admin Panel.
The default is that all users will have to login and this should not be enabled for environments where data needs to protected.
#### autoLogin Options
| Option | Description |
| ----------------- | --------------------------------------------------------------------------------------------------------------- |
| **`email`** | The email address of the user to login as |
| **`password`** | The password of the user to login as |
| **`prefillOnly`** | If set to true, the login credentials will be prefilled but the user will still need to click the login button. |
The recommended way to use this feature is behind an environment variable to ensure it is disabled when in production.
**Example:**
```ts
export default buildConfig({
admin: {
user: 'users',
// highlight-start
autoLogin:
process.env.PAYLOAD_PUBLIC_ENABLE_AUTOLOGIN === 'true'
? {
email: 'test@example.com',
password: 'test',
prefillOnly: true,
}
: false,
// highlight-end
},
collections: [
/** */
],
})
```

View File

@@ -1,19 +1,16 @@
---
title: Cookie Strategy
label: Cookie Strategy
order: 30
order: 40
desc: Enable HTTP Cookie based authentication to interface with Payload.
keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Payload `login`, `logout`, and `refresh` operations make use of HTTP-only cookies for authentication purposes.
Payload offers the ability to [Authenticate](./overview) via HTTP-only cookies. These can be read from the responses of `login`, `logout`, `refresh`, and `me` auth operations.
<Banner type="success">
<strong>Tip:</strong>
<br />
You can access the logged-in user from [Access Control](../access-control/overview) functions and hooks from the `req.user` property.
<br />
[Learn more about token data](/docs/authentication/token-data).
You can access the logged-in user from within [Access Control](../access-control/overview) and [Hooks](../hooks/overview) through the `req.user` argument. [More details](./token-data).
</Banner>
### Automatic browser inclusion
@@ -38,7 +35,6 @@ For more about including cookies in requests from your app to your Payload API,
<Banner type="success">
<strong>Tip:</strong>
<br />
To make sure you have a Payload cookie set properly in your browser after logging in, you can use
the browsers Developer Tools > Application > Cookies > [your-domain-here]. The Developer tools
will still show HTTP-only cookies.

View File

@@ -13,7 +13,7 @@ keywords: authentication, config, configuration, overview, documentation, Conten
### Creating a strategy
At the core, a strategy is a way to authenticate a user making a request. As of `3.0` we moved away from passportJS in favor of pulling back the curtain and putting you in full control.
At the core, a strategy is a way to authenticate a user making a request. As of `3.0` we moved away from [Passport](https://www.passportjs.org) in favor of pulling back the curtain and putting you in full control.
A strategy is made up of the following:

View File

@@ -0,0 +1,203 @@
---
title: Authentication Emails
label: Email Verification
order: 30
desc: Email Verification allows users to verify their email address before they're account is fully activated. Email Verification ties directly into the Email functionality that Payload provides.
keywords: authentication, email, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
[Authentication](./overview) ties directly into the [Email](../email) functionality that Payload provides. This allows you to send emails to users for verification, password resets, and more. While Payload provides default email templates for these actions, you can customize them to fit your brand.
## Email Verification
Email Verification forces users to prove they have access to the email address they can authenticate. This will help to reduce spam accounts and ensure that users are who they say they are.
To enable Email Verification, use the `auth.verify` property on your [Collection Config](../configuration/collections):
```ts
import { CollectionConfig } from 'payload'
export const Customers: CollectionConfig = {
// ...
auth: {
verify: true // highlight-line
},
}
```
<Banner type="info">
<strong>Tip:</strong>
Verification emails are fully customizable. [More details](#generateEmailHTML).
</Banner>
The following options are available:
| Option | Description |
|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **`generateEmailHTML`** | Allows for overriding the HTML within emails that are sent to users indicating how to validate their account. [More details](#generateEmailHTML). |
| **`generateEmailSubject`** | Allows for overriding the subject of the email that is sent to users indicating how to validate their account. [More details](#generateEmailSubject). |
#### generateEmailHTML
Function that accepts one argument, containing `{ req, token, user }`, that allows for overriding the HTML within emails that are sent to users indicating how to validate their account. The function should return a string that supports HTML, which can optionally be a full HTML email.
```ts
import { CollectionConfig } from 'payload'
export const Customers: CollectionConfig = {
// ...
auth: {
verify: {
// highlight-start
generateEmailHTML: ({ req, token, user }) => {
// Use the token provided to allow your user to verify their account
const url = `https://yourfrontend.com/verify?token=${token}`
return `Hey ${user.email}, verify your email by clicking here: ${url}`
},
// highlight-end
},
},
}
```
<Banner type="warning">
<strong>Important:</strong>
If you specify a different URL to send your users to for email verification, such as a page on the
frontend of your app or similar, you need to handle making the call to the Payload REST or GraphQL
verification operation yourself on your frontend, using the token that was provided for you.
Above, it was passed via query parameter.
</Banner>
#### generateEmailSubject
Similarly to the above `generateEmailHTML`, you can also customize the subject of the email. The function argument are the same but you can only return a string - not HTML.
```ts
import { CollectionConfig } from 'payload'
export const Customers: CollectionConfig = {
// ...
auth: {
verify: {
// highlight-start
generateEmailSubject: ({ req, user }) => {
return `Hey ${user.email}, reset your password!`;
}
// highlight-end
}
}
}
```
## Forgot Password
You can customize how the Forgot Password workflow operates with the following options on the `auth.forgotPassword` property:
```ts
import { CollectionConfig } from 'payload'
export const Customers: CollectionConfig = {
// ...
auth: {
forgotPassword: { // highlight-line
// ...
},
},
}
```
The following options are available:
| Option | Description |
|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **`generateEmailHTML`** | Allows for overriding the HTML within emails that are sent to users attempting to reset their password. [More details](#generateEmailHTML). |
| **`generateEmailSubject`** | Allows for overriding the subject of the email that is sent to users attempting to reset their password. [More details](#generateEmailSubject). |
#### generateEmailHTML
This function allows for overriding the HTML within emails that are sent to users attempting to reset their password. The function should return a string that supports HTML, which can be a full HTML email.
```ts
import { CollectionConfig } from 'payload'
export const Customers: CollectionConfig = {
// ...
auth: {
forgotPassword: {
// highlight-start
generateEmailHTML: ({ req, token, user }) => {
// Use the token provided to allow your user to reset their password
const resetPasswordURL = `https://yourfrontend.com/reset-password?token=${token}`
return `
<!doctype html>
<html>
<body>
<h1>Here is my custom email template!</h1>
<p>Hello, ${user.email}!</p>
<p>Click below to reset your password.</p>
<p>
<a href="${resetPasswordURL}">${resetPasswordURL}</a>
</p>
</body>
</html>
`
},
// highlight-end
},
},
}
```
<Banner type="warning">
<strong>Important:</strong>
If you specify a different URL to send your users to for resetting their password, such as a page
on the frontend of your app or similar, you need to handle making the call to the Payload REST or
GraphQL reset-password operation yourself on your frontend, using the token that was provided for
you. Above, it was passed via query parameter.
</Banner>
<Banner type="success">
<strong>Tip:</strong>
HTML templating can be used to create custom email templates, inline CSS automatically, and more.
You can make a reusable function that standardizes all email sent from Payload, which makes
sending custom emails more DRY. Payload doesn't ship with an HTML templating engine, so you are
free to choose your own.
</Banner>
The following arguments are passed to the `generateEmailHTML` function:
| Argument | Description |
|----------|-----------------------------------------------------------------------------------------------|
| `req` | The request object. |
| `token` | The token that is generated for the user to reset their password. |
| `user` | The user document that is attempting to reset their password. |
#### generateEmailSubject
Similarly to the above `generateEmailHTML`, you can also customize the subject of the email. The function argument are the same but you can only return a string - not HTML.
```ts
import { CollectionConfig } from 'payload'
export const Customers: CollectionConfig = {
// ...
auth: {
forgotPassword: {
// highlight-start
generateEmailSubject: ({ req, user }) => {
return `Hey ${user.email}, reset your password!`;
}
// highlight-end
}
}
}
```
The following arguments are passed to the `generateEmailSubject` function:
| Argument | Description |
|----------|-----------------------------------------------------------------------------------------------|
| `req` | The request object. |
| `user` | The user document that is attempting to reset their password. |

View File

@@ -6,14 +6,11 @@ desc: Enable JSON Web Token based authentication to interface with Payload.
keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Payload offers the ability to authenticate via `JWT` (JSON web token). These can be read from the responses of `login`, `refresh`, and `me` auth operations.
Payload offers the ability to [Authenticate](./overview) via JSON Web Tokens (JWT). These can be read from the responses of `login`, `logout`, `refresh`, and `me` auth operations.
<Banner type="success">
<strong>Tip:</strong>
<br />
You can access the logged-in user from [Access Control](../access-control/overview) functions and hooks from the `req.user` property.
<br />
[Learn more about token data](/docs/authentication/token-data).
You can access the logged-in user from within [Access Control](../access-control/overview) and [Hooks](../hooks/overview) through the `req.user` argument. [More details](./token-data).
</Banner>
### Identifying Users Via The Authorization Header

View File

@@ -1,12 +1,12 @@
---
title: Authentication Operations
label: Operations
order: 80
order: 20
desc: Enabling Authentication automatically makes key operations available such as Login, Logout, Verify, Unlock, Reset Password and more.
keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Enabling Authentication on a Collection automatically exposes additional auth-based operations in the Local, REST, and GraphQL APIs.
Enabling [Authentication](./overview) on a [Collection](../configuration/collections) automatically exposes additional auth-based operations in the [Local API](../local-api/overview), [REST API](../rest-api/overview), and [GraphQL API](../graphql/overview).
## Access
@@ -308,7 +308,7 @@ Payload comes with built-in forgot password functionality. Submitting an email a
The link to reset the user's password contains a token which is what allows the user to securely reset their password.
By default, the Forgot Password operations send users to the [Admin Panel](../admin/overview) to reset their password, but you can customize the generated email to send users to the frontend of your app instead by [overriding the email HTML](/docs/authentication/config#forgot-password).
By default, the Forgot Password operations send users to the [Admin Panel](../admin/overview) to reset their password, but you can customize the generated email to send users to the frontend of your app instead by [overriding the email HTML](/docs/authentication/overview#forgot-password).
**Example REST API Forgot Password**:

View File

@@ -11,38 +11,47 @@ keywords: authentication, config, configuration, overview, documentation, Conten
title="Simplified Authentication for Headless CMS: Unlocking Reusability in One Line"
/>
<Banner>
Payload provides for highly secure and customizable user Authentication out of the box, which
allows for users to identify themselves to Payload.
</Banner>
Authentication is a critical part of any application. Payload provides a secure, portable way to manage user accounts out of the box. Payload Authentication is designed to be used in both the [Admin Panel](../admin/overview), all well as your own external applications, completely eliminating the need for paid, third-party platforms and services.
Authentication is used within the [Admin Panel](../admin/overview) itself as well as throughout your app(s) themselves however you determine necessary.
Here are some common use cases of Authentication in your own applications:
- Customer accounts for an e-commerce app
- User accounts for a SaaS product
- P2P apps or social sites where users need to log in and manage their profiles
- Online games where players need to track their progress over time
When Authentication is enabled on a [Collection](../configuration/collections), Payload injects all necessary functionality to support the entire user flow. This includes all [auth-related operations](./operations) like account creation, logging in and out, and resetting passwords, all [auth-related emails](./email) like email verification and password reset, as well as any necessary UI to manage users from the Admin Panel.
To enable Authentication on a Collection, use the `auth` property in the [Collection Config](../configuration/collection#auth):
```ts
import { CollectionConfig } from 'payload'
export const Users: CollectionConfig = {
// ...
auth: true, // highlight-line
}
```
![Authentication Admin Panel functionality](https://payloadcms.com/images/docs/auth-admin.jpg)
_Admin Panel screenshot depicting an Admins Collection with Auth enabled_
**Here are some common use cases of Authentication outside of Payload's dashboard itself:**
## Config Options
- Customer accounts for an ecommerce app
- Customer accounts for a SaaS product
- P2P app or social site where users need to log in and manage their profiles
- Online game where players need to track their progress over time
Any [Collection](../configuration/collections) can opt-in to supporting Authentication. Once enabled, each Document that is created within the Collection can be thought of as a "user". This enables a complete authentication workflow on your Collection, such as logging in and out, resetting their password, and more.
By default, Payload provides you with a `User` collection that supports Authentication, which is used to access the [Admin Panel](../admin/overview). But, you can add support to one or many Collections of your own. For more information on how to customize, override, or remove the default `User` collection, [click here](/docs/admin/overview#the-admin-user-collection).
<Banner type="warning">
<strong>Note:</strong>
By default, Payload provides an auth-enabled `User` Collection which is used to access the Admin Panel. [More details](../admin/overview#the-admin-user-collection).
</Banner>
## Enabling Auth on a collection
Every Payload Collection can opt-in to supporting Authentication by specifying the `auth` property on the Collection's config to either `true` or to an object containing `auth` options.
**For a full list of all `auth` options, [click here](/docs/authentication/config).**
Simple example collection:
To enable Authentication on a Collection, use the `auth` property in the [Collection Config](../configuration/collections):
```ts
import { CollectionConfig } from 'payload'
export const Admins: CollectionConfig = {
slug: 'admins',
// ...
// highlight-start
auth: {
tokenExpiration: 7200, // How many seconds to keep the user logged in
@@ -52,53 +61,136 @@ export const Admins: CollectionConfig = {
// More options are available
},
// highlight-end
fields: [
{
name: 'role',
type: 'select',
required: true,
options: ['user', 'admin', 'editor', 'developer'],
},
],
}
```
**By enabling Authentication on a config, the following modifications will automatically be made to your Collection:**
<Banner type="info">
<strong>Tip:</strong>
For default auth behavior, set `auth: true`. This is a good starting point for most applications.
</Banner>
1. `email` as well as password `salt` & `hash` fields will be added to your Collection's schema
1. The [Admin Panel](../admin/overview) will feature a new set of corresponding UI to allow for changing password and editing email
1. [A new set of `operations`](/docs/authentication/operations) will be exposed via Payload's REST, Local, and GraphQL APIs
<Banner type="warning">
<strong>Note:</strong>
Auth-enabled Collections with be automatically injected with the `hash`, `salt`, and `email` fields. [More details](../fields/overview#field-names).
</Banner>
Once enabled, each document that is created within the Collection can be thought of as a `user` - who can make use of commonly required authentication functions such as logging in / out, resetting their password, and more.
The following options are available:
## Authentication Strategies
| Option | Description |
|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **`cookies`** | Set cookie options, including `secure`, `sameSite`, and `domain`. For advanced users. |
| **`depth`** | How many levels deep a `user` document should be populated when creating the JWT and binding the `user` to the `req`. Defaults to `0` and should only be modified if absolutely necessary, as this will affect performance. |
| **`disableLocalStrategy`** | Advanced - disable Payload's built-in local auth strategy. Only use this property if you have replaced Payload's auth mechanisms with your own. |
| **`forgotPassword`** | Customize the way that the `forgotPassword` operation functions. [More details](./email#forgot-password). |
| **`lockTime`** | Set the time (in milliseconds) that a user should be locked out if they fail authentication more times than `maxLoginAttempts` allows for. |
| **`loginWithUsername`** | Ability to allow users to login with username/password. [More](/docs/authentication/overview#login-with-username) |
| **`maxLoginAttempts`** | Only allow a user to attempt logging in X amount of times. Automatically locks out a user from authenticating if this limit is passed. Set to `0` to disable. |
| **`strategies`** | Advanced - an array of custom authentification strategies to extend this collection's authentication with. [More details](./custom-strategies). |
| **`tokenExpiration`** | How long (in seconds) to keep the user logged in. JWTs and HTTP-only cookies will both expire at the same time. |
| **`useAPIKey`** | Payload Authentication provides for API keys to be set on each user within an Authentication-enabled Collection. [More details](./api-keys). |
| **`verify`** | Set to `true` or pass an object with verification options to require users to verify by email before they are allowed to log into your app. [More details](./email#email-verification). |
Out of the box Payload ships with a few powerful authentication strategies. HTTP-Only Cookies, JWT's and API-Keys, they can work together or individually. You can also have multiple collections that have auth enabled, but only 1 of them can be used to log into the Admin Panel.
### Login With Username
You can allow users to login with their username instead of their email address by setting the `loginWithUsername` property to `true`.
Example:
```ts
{
slug: 'customers',
auth: {
loginWithUsername: true,
},
}
```
Or, you can pass an object with additional options:
```ts
{
slug: 'customers',
auth: {
loginWithUsername: {
allowEmailLogin: true, // default: false
requireEmail: false, // default: false
},
},
}
```
**`allowEmailLogin`**
If set to `true`, users can log in with either their username or email address. If set to `false`, users can only log in with their username.
**`requireEmail`**
If set to `true`, an email address is required when creating a new user. If set to `false`, email is not required upon creation.
## Auto-Login
For testing and demo purposes you may want to skip forcing the user to login in order to access your application. Typically, all users should be required to login, however, you can speed up local development time by enabling auto-login.
To enable auto-login, set the `autoLogin` property in the [Admin Config](../configuration/admin):
```ts
import { buildConfig } from 'payload'
export default buildConfig({
// ...
// highlight-start
autoLogin:
process.env.NEXT_PUBLIC_ENABLE_AUTOLOGIN === 'true'
? {
email: 'test@example.com',
password: 'test',
prefillOnly: true,
}
: false,
// highlight-end
})
```
<Banner type="warning">
<strong>Warning:</strong>
The recommended way to use this feature is behind an [Environment Variable](../configuration/environment-vars). This will ensure it is _disabled_ in production.
</Banner>
The following options are available:
| Option | Description |
|-------------------|-----------------------------------------------------------------------------------------------------------------|
| **`username`** | The username of the user to login as |
| **`email`** | The email address of the user to login as |
| **`password`** | The password of the user to login as. This is only needed if `prefillOnly` is set to true |
| **`prefillOnly`** | If set to true, the login credentials will be prefilled but the user will still need to click the login button. |
## Operations
All auth-related operations are available via Payload's REST, Local, and GraphQL APIs. These operations are automatically added to your Collection when you enable Authentication. [More details](./operations).
## Strategies
Out of the box Payload ships with a three powerful Authentication strategies:
- [HTTP-Only Cookies](./cookies)
- [JSON Web Tokens (JWT)](./jwt)
- [API-Keys](./api-keys)
Each of these strategies can work together or independently. You can also create your own custom strategies to fit your specific needs. [More details](./custom-strategies).
### HTTP-Only Cookies
HTTP-only cookies are a highly secure method of storing identifiable data on a user's device so that Payload can automatically recognize a returning user until their cookie expires. They are totally protected from common XSS attacks and <strong>cannot be read by JavaScript in the browser</strong>, unlike JWT's.
You can learn more about this strategy from the [HTTP-Only Cookies](/docs/authentication/http-only-cookies) docs.
[HTTP-only cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) are a highly secure method of storing identifiable data on a user's device so that Payload can automatically recognize a returning user until their cookie expires. They are totally protected from common XSS attacks and <strong>cannot be read by JavaScript in the browser</strong>, unlike JWT's. [More details](./cookies).
### JSON Web Tokens
JWT (JSON Web Tokens) can also be utilized to perform authentication. Tokens are generated on `login`, `refresh` and `me` operations and can be attached to future requests to authenticate users.
You can learn more about this strategy from the [JWT](/docs/authentication/jwt) docs.
JWT (JSON Web Tokens) can also be utilized to perform authentication. Tokens are generated on `login`, `refresh` and `me` operations and can be attached to future requests to authenticate users. [More details](./jwt).
### API Keys
API Keys can be enabled on auth collections. These are particularly useful when you want to authenticate against Payload from a third party service.
You can learn more about this strategy from the [API Keys](/docs/authentication/api-keys) docs.
API Keys can be enabled on auth collections. These are particularly useful when you want to authenticate against Payload from a third party service. [More details](./api-keys).
### Custom Strategies
There are cases where these may not be enough for your application. Payload is extendable by design so you can wire up your own strategy when you need to.
You can learn more about custom strategies from the [Custom Strategies](/docs/authentication/custom-strategies) docs.
## Logging in / out, resetting password, etc.
[Click here](/docs/authentication/operations) for a list of all automatically-enabled Auth operations, including `login`, `logout`, `refresh`, and others.
There are cases where these may not be enough for your application. Payload is extendable by design so you can wire up your own strategy when you need to. [More details](./custom-strategies).

View File

@@ -59,9 +59,7 @@ You can update settings from your Projects Settings tab. Changes to your buil
From the Environment Variables page of the Settings tab, you can add, update and delete variables for use in your project. Like build settings, these changes will trigger a redeployment of your project.
<Banner>
Note: For security reasons, any variables you wish to provide to the [Admin Panel](../admin/overview) must be prefixed
with `PAYLOAD_PUBLIC_`.  Learn more
[here](../configuration/environment-vars).
Note: For security reasons, any variables you wish to provide to the [Admin Panel](../admin/overview) must be prefixed with `NEXT_PUBLIC_`. [More details](../configuration/environment-vars).
</Banner>
## Custom Domains

View File

@@ -6,9 +6,9 @@ desc: Structure your Collections for your needs by defining fields, adding slugs
keywords: collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
A Collection is a group of records, called Documents, that all share a common schema. You can define as many Collections as your application needs. Each Collection saves to the [Database](../database/overview) based on the [Fields](../fields/overview) that you define, and automatically generates the [Local API](../local-api/overview), [REST API](../rest-api/overview), and [GraphQL API](../graphql/overview) to manage your Documents.
A Collection is a group of records, called Documents, that all share a common schema. You can define as many Collections as your application needs. Each Document in a Collection is stored in the [Database](../database/overview) based on the [Fields](../fields/overview) that you define, and automatically generates a [Local API](../local-api/overview), [REST API](../rest-api/overview), and [GraphQL API](../graphql/overview) used to manage your Documents.
Collections are also the primary way to achieve [Authentication](../authentication/overview) in Payload. By defining a Collection with `auth` options, that Collection receives additional operations to support user authentication.
Collections are also used to achieve [Authentication](../authentication/overview) in Payload. By defining a Collection with `auth` options, that Collection receives additional operations to support user authentication.
Collections are the primary way to structure recurring data in your application, such as users, products, pages, posts, and other types of content that you might want to manage. Each Collection can have its own unique [Access Control](../access-control/overview), [Hooks](../hooks/overview), [Admin Options](#admin-options), and more.
@@ -59,15 +59,15 @@ The following options are available:
| Option | Description |
|------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **`admin`** | The configuration options for the Admin Panel. [More details](#admin-options). |
| **`admin`** | The configuration options for the Admin Panel. [More details](../admin/collections). |
| **`access`** | Provide Access Control functions to define exactly who should be able to do what with Documents in this Collection. [More details](../access-control/collections). |
| **`auth`** | Specify options if you would like this Collection to feature authentication. For more, consult the [Authentication](../authentication/config) documentation. |
| **`auth`** | Specify options if you would like this Collection to feature authentication. [More details](../authentication/overview). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`disableDuplicate`** | When true, do not show the "Duplicate" button while editing documents within this Collection and prevent `duplicate` from all APIs. |
| **`defaultSort`** | Pass a top-level field to sort by default in the Collection List View. Prefix the name of the field with a minus symbol ("-") to sort in descending order. |
| **`dbName`** | Custom table or Collection name depending on the Database Adapter. Auto-generated from slug if not defined. |
| **`endpoints`** | Add custom routes to the REST API. Set to `false` to disable routes. [More details](../rest-api/overview#custom-endpoints). |
| **`fields`** \* | Array of field types that will determine the structure and functionality of the data stored within this Collection. [Click here](../fields/overview) for a full list of field types as well as how to configure them. |
| **`fields`** \* | Array of field types that will determine the structure and functionality of the data stored within this Collection. [More details](../fields/overview). |
| **`graphQL`** | An object with `singularName` and `pluralName` strings used in schema generation. Auto-generated from slug if not defined. Set to `false` to disable GraphQL. |
| **`hooks`** | Entry point for Hooks. [More details](../hooks/overview#collection-hooks). |
| **`labels`** | Singular and plural labels for use in identifying this Collection throughout Payload. Auto-generated from slug if not defined. |
@@ -93,145 +93,14 @@ Fields define the schema of the Documents within a Collection. To learn more, go
### Admin Options
You can customize the way that the [Admin Panel](../admin/overview) behaves on a Collection-by-Collection basis.
To configure Admin Options for Collections, use the `admin` property in your Collection Config:
```ts
import { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
admin: { // highlight-line
// ...
},
}
```
The following options are available:
| Option | Description |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`group`** | Text used as a label for grouping Collection and Global links together in the navigation. |
| **`hidden`** | Set to true or a function, called with the current user, returning true to exclude this Collection from navigation and admin routing. |
| **`hooks`** | Admin-specific hooks for this Collection. [More details](#admin-hooks). |
| **`useAsTitle`** | Specify a top-level field to use for a document title throughout the [Admin Panel](../admin/overview). If no field is defined, the ID of the document is used as the title. |
| **`description`** | Text or React component to display below the Collection label in the List View to give editors more information. |
| **`defaultColumns`** | Array of field names that correspond to which columns to show by default in this Collection's List View. |
| **`hideAPIURL`** | Hides the "API URL" meta field while editing documents within this Collection. |
| **`enableRichTextLink`** | The [Rich Text](../fields/rich-text) field features a `Link` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
| **`enableRichTextRelationship`** | The [Rich Text](../fields/rich-text) field features a `Relationship` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
| **`meta`** | Metadata overrides to apply to the [Admin Panel](../admin/overview). Included properties are `description` and `openGraph`. |
| **`preview`** | Function to generate preview URLs within the [Admin Panel](../admin/overview) that can point to your app. [More details](#preview). |
| **`livePreview`** | Enable real-time editing for instant visual feedback of your front-end application. [More details](../live-preview/overview). |
| **`components`** | Swap in your own React components to be used within this Collection. [More details](../admin/components#collections). |
| **`listSearchableFields`** | Specify which fields should be searched in the List search view. [More details](#list-searchable-fields). |
| **`pagination`** | Set pagination-specific options for this Collection. [More details](#pagination). |
#### Preview
It is possible to display a Preview Button in the Admin Panel within the Edit View. This will allow editors to visit the frontend of your app the corresponds to the document they are actively editing. This way they can preview the latest, potentially unpublished changes.
To configure the Preview Button, set the `admin.preview` property to a function in your Collection Config:
```ts
import { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
admin: {
// highlight-start
preview: (doc, { locale }) => {
if (doc?.slug) {
return `/${doc.slug}?locale=${locale}`
}
return null
},
// highlight-end
},
}
```
The preview function receives two arguments:
| Argument | Description |
| --- | --- |
| **`doc`** | The document being edited |
| **`ctx`** | An object containing `locale` and `token` properties. The `token` is the currently logged-in user's JWT. |
<Banner type="success">
<strong>Reminder:</strong>
For fully working example of this, check of the official [Draft Preview Example](https://github.com/payloadcms/payload/tree/main/examples/draft-preview) in the [Examples Directory](https://github.com/payloadcms/payload/tree/main/examples).
</Banner>
#### Pagination
All Collections receive their own List View which displays a paginated list of documents that can be sorted and filtered. The pagination behavior of the List View can be customized on a per-Collection basis.
To configure pagination options, use the `admin.pagination` property in your Collection Config:
```ts
import { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
admin: {
// highlight-start
pagination: {
defaultLimit: 10,
limits: [10, 20, 50],
},
// highlight-end
},
}
```
The following options are available:
| Option | Description |
| -------------- | --------------------------------------------------------------------------------------------------- |
| `defaultLimit` | Integer that specifies the default per-page limit that should be used. Defaults to 10. |
| `limits` | Provide an array of integers to use as per-page options for admins to choose from in the List View. |
#### List Searchable Fields
In the List View, there is a "search" box that allows you to quickly find a document through a simple text search. By default, it searches on the ID field. If defined, the `admin.useAsTitle` field is used. Or, you can explicitly define which fields to search based on the needs of your application.
To define which fields should be searched, use the `admin.listSearchableFields` property in your Collection Config:
```ts
import { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
admin: {
// highlight-start
listSearchableFields: ['title', 'slug'],
// highlight-end
},
}
```
<Banner type="warning">
<strong>Tip:</strong>
If you are adding `listSearchableFields`, make sure you index each of these fields so your admin queries can remain performant.
</Banner>
You can customize the way that the [Admin Panel](../admin/overview) behaves on a Collection-by-Collection basis. To learn more, go to the [Collection Admin Options](../admin/collections) documentation.
## TypeScript
You can import Collection types as follows:
You can import types from Payload to help make writing your Collection configs easier and type-safe. There are two main types that represent the Collection Config, `CollectionConfig` and `SanitizeCollectionConfig`.
The `CollectionConfig` type represents a raw Collection Config in its full form, where only the bare minimum properties are marked as required. The `SanitizedCollectionConfig` type represents a Collection Config after it has been fully sanitized. Generally, this is only used internally by Payload.
```ts
import { CollectionConfig } from 'payload'
// This is the type used for incoming Collection configs.
// Only the bare minimum properties are marked as required.
```
```ts
import { SanitizedCollectionConfig } from 'payload'
// This is the type used after an incoming Collection config is fully sanitized.
// Generally, this is only used internally by Payload.
import type { CollectionConfig, SanitizedCollectionConfig } from 'payload'
```

View File

@@ -6,7 +6,7 @@ desc: Set up your Global config for your needs by defining fields, adding slugs
keywords: globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Globals are in many ways similar to [Collections](../configuration/collections), except they correspond to only a single Document. You can define as many Globals as your application needs. Each Global saves to the [Database](../database/overview) based on the [Fields](../fields/overview) that you define, and automatically generates the [Local API](../local-api/overview), [REST API](../rest-api/overview), and [GraphQL API](../graphql/overview) to manage your Documents.
Globals are in many ways similar to [Collections](../configuration/collections), except they correspond to only a single Document. You can define as many Globals as your application needs. Each Global Document is stored in the [Database](../database/overview) based on the [Fields](../fields/overview) that you define, and automatically generates a [Local API](../local-api/overview), [REST API](../rest-api/overview), and [GraphQL API](../graphql/overview) used to manage your Documents.
Globals are the primary way to structure singletons in Payload, such as a header navigation, site-wide banner alerts, or app-wide localized strings. Each Global can have its own unique [Access Control](../access-control/overview), [Hooks](../hooks/overview), [Admin Options](#admin-options), and more.
@@ -68,12 +68,12 @@ The following options are available:
| Option | Description |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`access`** | Provide Access Control functions to define exactly who should be able to do what with this Global. [More details](../access-control/globals). |
| **`admin`** | The configuration options for the Admin Panel. [More details](#admin-options). |
| **`admin`** | The configuration options for the Admin Panel. [More details](../admin/globals). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`dbName`** | Custom table or collection name for this Global depending on the Database Adapter. Auto-generated from slug if not defined. |
| **`description`** | Text or React component to display below the Global header to give editors more information. |
| **`endpoints`** | Add custom routes to the REST API. [More details](../rest-api/overview#custom-endpoints). |
| **`fields`** \* | Array of field types that will determine the structure and functionality of the data stored within this Global. [Click here](../fields/overview) for a full list of field types as well as how to configure them. |
| **`fields`** \* | Array of field types that will determine the structure and functionality of the data stored within this Global. [More details](../fields/overview). |
| **`graphQL.name`** | Text used in schema generation. Auto-generated from slug if not defined. |
| **`hooks`** | Entry point for Hooks. [More details](../hooks/overview#global-hooks). |
| **`label`** | Text for the name in the Admin Panel or an object with keys for each language. Auto-generated from slug if not defined. |
@@ -97,84 +97,14 @@ Fields define the schema of the Global. To learn more, go to the [Fields](../fie
### Admin Options
You can customize the way that the [Admin Panel](../admin/overview) behaves on a Global-by-Global basis.
To configure Admin Options for Globals, use the `admin` property in your Global Config:
```ts
import { GlobalConfig } from 'payload'
const MyGlobal: GlobalConfig = {
// ...
admin: { // highlight-line
// ...
},
}
```
The following options are available:
| Option | Description |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| **`group`** | Text used as a label for grouping Collection and Global links together in the navigation. |
| **`hidden`** | Set to true or a function, called with the current user, returning true to exclude this Global from navigation and admin routing. |
| **`components`** | Swap in your own React components to be used within this Global. [More details](../admin/components#globals). |
| **`preview`** | Function to generate a preview URL within the [Admin Panel](../admin/overview) for this Global that can point to your app. [More details](#preview). |
| **`livePreview`** | Enable real-time editing for instant visual feedback of your front-end application. [More details](../live-preview/overview). |
| **`hideAPIURL`** | Hides the "API URL" meta field while editing documents within this collection. |
| **`meta`** | Metadata overrides to apply to the [Admin Panel](../admin/overview). Included properties are `description` and `openGraph`. |
#### Preview
It is possible to display a Preview Button in the Admin Panel within the Edit View. This will allow editors to visit the frontend of your app the corresponds to the document they are actively editing. This way they can preview the latest, potentially unpublished changes.
To configure the Preview Button, set the `admin.preview` property to a function in your Global Config:
```ts
import { GlobalConfig } from 'payload'
export const MainMenu: GlobalConfig = {
// ...
admin: {
// highlight-start
preview: (doc, { locale }) => {
if (doc?.slug) {
return `/${doc.slug}?locale=${locale}`
}
return null
},
// highlight-end
},
}
```
The preview function receives two arguments:
| Argument | Description |
| --- | --- |
| **`doc`** | The document being edited |
| **`ctx`** | An object containing `locale` and `token` properties. The `token` is the currently logged-in user's JWT. |
<Banner type="success">
<strong>Reminder:</strong>
For fully working example of this, check of the official [Draft Preview Example](https://github.com/payloadcms/payload/tree/main/examples/draft-preview) in the [Examples Directory](https://github.com/payloadcms/payload/tree/main/examples).
</Banner>
You can customize the way that the [Admin Panel](../admin/overview) behaves on a Global-by-Global basis. To learn more, go to the [Global Admin Options](../admin/globals) documentation.
## TypeScript
You can import Global types as follows:
You can import types from Payload to help make writing your Global configs easier and type-safe. There are two main types that represent the Global Config, `GlobalConfig` and `SanitizeGlobalConfig`.
The `GlobalConfig` type represents a raw Global Config in its full form, where only the bare minimum properties are marked as required. The `SanitizedGlobalConfig` type represents a Global Config after it has been fully sanitized. Generally, this is only used internally by Payload.
```ts
import { GlobalConfig } from 'payload'
// This is the type used for incoming Global configs.
// Only the bare minimum properties are marked as required.
```
```ts
import { SanitizedGlobalConfig } from 'payload'
// This is the type used after an incoming Global config is fully sanitized.
// Generally, this is only used internally by Payload.
import type { GlobalConfig, SanitizedGlobalConfig } from 'payload'
```

View File

@@ -36,7 +36,6 @@ 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,
@@ -58,56 +57,56 @@ export default buildConfig({
```
<Banner type="success">
<strong>Reminder:</strong>
<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 with the `payload` bin function. |
| **`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 including 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](#cors) |
| **`localization`** | Opt-in and control how Payload handles the translation of 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 cookies to be accepted from as a form of CSRF protection. [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`. |
| **`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. Specify `admin`, `api`, `graphQL`, and `graphQLPlayground`. [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`** | Tap into Payload-wide hooks. [More details](../hooks/overview). |
| **`plugins`** | An array of Payload plugins. [More details](../plugins/overview). |
| **`endpoints`** | An array of custom API 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). |
| 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>Reminder:</strong>
<strong>Note:</strong>
Some properties are removed from the client-side bundle. [More details](../admin/components#accessing-the-payload-config).
</Banner>
### TypeScript
### 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](../typescript/overview) for all Local API methods.
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:
@@ -130,39 +129,59 @@ The following options are available:
| **`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. |
#### Importing Payload Config types
You can import config types as follows:
```ts
import { Config } from 'payload'
// This is the type used for an incoming Payload Config.
// Only the bare minimum properties are marked as required.
```
```ts
import { SanitizedConfig } from 'payload'
// This is the type used after an incoming Payload Config is fully sanitized.
// Generally, this is only used internally by Payload.
```
## 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 the root current working directory, your `tsconfig`'s `rootDir`, and your `tsconfig`'s `outDir`.
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:
In development mode, if the configuration file is not found at the root, Payload will attempt to read your `tsconfig.json`, and search in the directory specified in `compilerOptions.rootDir` (typically "src").
1. The root current working directory
1. The `compilerOptions` in your `tsconfig`*
1. The `dist` directory*
In production mode, Payload will first attempt to find the config file in the output directory specified in `compilerOptions.outDir` of your `tsconfig.json`, then fallback to the source directory (`compilerOptions.rootDir`), and finally will check the 'dist' directory.
_\* Config location detection is different between development and production environments. See below for more details._
Please ensure your `tsconfig.json` is properly configured if you want Payload to accurately auto-detect your configuration file location. If `tsconfig.json` does not exist or doesn't specify `rootDir` or `outDir`, Payload will default to the current working directory.
<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 is done by using the environment variable `PAYLOAD_CONFIG_PATH`. The path you provide via this environment variable can either be absolute or relative to your current working directory. This can be useful in situations where your Payload Config is not in a standard location, or you wish to switch between multiple configurations.
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.
**Example in package.json:**
To use a custom config location, set the `PAYLOAD_CONFIG_PATH` environment variable:
```json
{
@@ -172,7 +191,10 @@ In addition to the above automated detection, you can specify your own location
}
```
When `PAYLOAD_CONFIG_PATH` is set, Payload will use this path to load the configuration, bypassing all automated detection.
<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
@@ -186,8 +208,8 @@ Cross-origin resource sharing (CORS) can be configured with either a whitelist a
| 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`. |
| **`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:
@@ -196,7 +218,7 @@ import { buildConfig } from 'payload/config'
export default buildConfig({
// ...
cors: '*'
cors: '*' // highlight-line
})
```
@@ -207,9 +229,27 @@ 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.

View File

@@ -211,3 +211,32 @@ In the example above, we've specified a `ci` script which we can use as our "bui
This will require that your build pipeline can connect to your database, and it will simply run the `payload migrate` command prior to starting the build process. By calling `payload migrate`, Payload will automatically execute any migrations in your `/migrations` folder that have not yet been executed against your production database, in the order that they were created.
If it fails, the deployment will be rejected. But now, with your build script set up to run your migrations, you will be all set! Next time you deploy, your CI will execute the required migrations for you, and your database will be caught up with the shape that your Payload Config requires.
## Running migrations in production
In certain cases, you might want to run migrations at runtime when the server starts. Running them during build time may be impossible due to not having access to your database connection while building or similar reasoning.
If you're using a long-running server or container where your Node server starts up one time and then stays initialized, you might prefer to run migrations on server startup instead of within your CI.
In order to run migrations at runtime, on initialization, you can pass your migrations to your database adapter under the `prodMigrations` key as follows:
```ts
// Import your migrations from the `index.ts` file
// that Payload generates for you
import { migrations } from './migrations'
import { buildConfig } from 'payload'
export default buildConfig({
// your config here
db: postgresAdapter({
// your adapter config here
prodMigrations: migrations
})
})
```
Passing your migrations as shown above will tell Payload, in production only, to execute any migrations that need to be run prior to completing the initialization of Payload. This is ideal for long-running services where Payload will only be initialized at startup.
<Banner type="warning">
Warning - if Payload is instructed to run migrations in production, this may slow down serverless cold starts on platforms such as Vercel. Generally, this option should only be used for long-running servers / containers.
</Banner>

View File

@@ -37,6 +37,7 @@ export default buildConfig({
| `disableIndexHints` | Set to true to disable hinting to MongoDB to use 'id' as index. This is currently done when counting documents for pagination, as it increases the speed of the count function used in that query. Disabling this optimization might fix some problems with AWS DocumentDB. Defaults to false |
| `migrationDir` | Customize the directory that migrations are stored. |
| `transactionOptions` | An object with configuration properties used in [transactions](https://www.mongodb.com/docs/manual/core/transactions/) or `false` which will disable the use of transactions. |
| `collation` | Enable language-specific string comparison with customizable options. Available on MongoDB 3.4+. Defaults locale to "en". Example: `{ strength: 3 }`. For a full list of collation options and their definitions, see the [MongoDB documentation](https://www.mongodb.com/docs/manual/reference/collation/). |
## Access to Mongoose models

View File

@@ -12,7 +12,7 @@ Currently, Payload officially supports the following Database Adapters:
- [MongoDB](/docs/database/mongodb) with [Mongoose](https://mongoosejs.com/)
- [Postgres](/docs/database/postgres) with [Drizzle](https://drizzle.team/)
- Coming soon: SQLite and MySQL using Drizzle.
- [SQLite](/docs/database/sqlite) with [Drizzle](https://drizzle.team/)
To configure a Database Adapter, use the `db` property in your [Payload Config](../configuration/overview):
@@ -59,7 +59,7 @@ You should prefer MongoDB if:
Many projects might call for more rigid database architecture where the shape of your data is strongly enforced at the database level. For example, if you know the shape of your data and it's relatively "flat", and you don't anticipate it to change often, your workload might suit relational databases like Postgres very well.
You should prefer a relational DB like Postgres if:
You should prefer a relational DB like Postgres or SQLite if:
- You are comfortable with [Migrations](./migrations)
- You require enforced data consistency at the database level

View File

@@ -8,18 +8,20 @@ keywords: Postgres, documentation, typescript, Content Management System, cms, h
To use Payload with Postgres, install the package `@payloadcms/db-postgres`. It leverages Drizzle ORM and `node-postgres` to interact with a Postgres database that you provide.
Alternatively, the `@payloadcms/db-vercel-postgres` package is also available and is optimized for use with Vercel.
It automatically manages changes to your database for you in development mode, and exposes a full suite of migration controls for you to leverage in order to keep other database environments in sync with your schema. DDL transformations are automatically generated.
To configure Payload to use Postgres, pass the `postgresAdapter` to your Payload Config as follows:
### Usage
`@payloadcms/db-postgres`:
```ts
import { postgresAdapter } from '@payloadcms/db-postgres'
export default buildConfig({
// Your config goes here
collections: [
// Collections go here
],
// Configure the Postgres adapter here
db: postgresAdapter({
// Postgres-specific arguments go here.
@@ -31,20 +33,37 @@ export default buildConfig({
})
```
`@payloadcms/db-vercel-postgres`:
```ts
import { vercelPostgresAdapter } from '@payloadcms/db-vercel-postgres'
export default buildConfig({
// Automatically uses proces.env.POSTGRES_URL if no options are provided.
db: vercelPostgresAdapter(),
// Optionally, can accept the same options as the @vercel/postgres package.
db: vercelPostgresAdapter({
pool: {
connectionString: process.env.DATABASE_URL
},
}),
})
```
## Options
| Option | Description |
|-----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `pool` \* | [Pool connection options](https://orm.drizzle.team/docs/quick-postgresql/node-postgres) that will be passed to Drizzle and `node-postgres`. |
| `push` | Disable Drizzle's [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push) in development mode. By default, `push` is enabled for development mode only. |
| `migrationDir` | Customize the directory that migrations are stored. |
| `logger` | The instance of the logger to be passed to drizzle. By default Payload's will be used. |
| `schemaName` | A string for the postgres schema to use, defaults to 'public'. |
| `localesSuffix` | A string appended to the end of table names for storing localized fields. Default is '_locales'. |
| `relationshipsSuffix` | A string appended to the end of table names for storing relationships. Default is '_rels'. |
| `versionsSuffix` | A string appended to the end of table names for storing versions. Defaults to '_v'. |
| Option | Description |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pool` \* | [Pool connection options](https://orm.drizzle.team/docs/quick-postgresql/node-postgres) that will be passed to Drizzle and `node-postgres` or to `@vercel/postgres` |
| `push` | Disable Drizzle's [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push) in development mode. By default, `push` is enabled for development mode only. |
| `migrationDir` | Customize the directory that migrations are stored. |
| `logger` | The instance of the logger to be passed to drizzle. By default Payload's will be used. |
| `schemaName` (experimental) | A string for the postgres schema to use, defaults to 'public'. |
| `idType` | A string of 'serial', or 'uuid' that is used for the data type given to id columns. |
| `transactionOptions` | A PgTransactionConfig object for transactions, or set to `false` to disable using transactions. [More details](https://orm.drizzle.team/docs/transactions) |
| `localesSuffix` | A string appended to the end of table names for storing localized fields. Default is '_locales'. |
| `relationshipsSuffix` | A string appended to the end of table names for storing relationships. Default is '_rels'. |
| `versionsSuffix` | A string appended to the end of table names for storing versions. Defaults to '_v'. |
## Access to Drizzle

81
docs/database/sqlite.mdx Normal file
View File

@@ -0,0 +1,81 @@
---
title: SQLite
label: SQLite
order: 60
desc: Payload supports SQLite through an officially supported Drizzle Database Adapter.
keywords: SQLite, documentation, typescript, Content Management System, cms, headless, javascript, node, react, nextjs
---
To use Payload with SQLite, install the package `@payloadcms/db-sqlite`. It leverages Drizzle ORM and `libSQL` to interact with a SQLite database that you provide.
It automatically manages changes to your database for you in development mode, and exposes a full suite of migration controls for you to leverage in order to keep other database environments in sync with your schema. DDL transformations are automatically generated.
To configure Payload to use SQLite, pass the `sqliteAdapter` to your Payload Config as follows:
```ts
import { sqliteAdapter } from '@payloadcms/db-sqlite'
export default buildConfig({
// Your config goes here
collections: [
// Collections go here
],
// Configure the SQLite adapter here
db: sqliteAdapter({
// SQLite-specific arguments go here.
// `client.url` is required.
client: {
url: process.env.DATABASE_URL,
authToken: process.env.DATABASE_AUTH_TOKEN,
}
}),
})
```
## Options
| Option | Description |
|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `client` \* | [Client connection options](https://orm.drizzle.team/docs/get-started-sqlite#turso) that will be passed to `createClient` from `@libsql/client`. |
| `push` | Disable Drizzle's [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push) in development mode. By default, `push` is enabled for development mode only. |
| `migrationDir` | Customize the directory that migrations are stored. |
| `logger` | The instance of the logger to be passed to drizzle. By default Payload's will be used. |
| `transactionOptions` | A SQLiteTransactionConfig object for transactions, or set to `false` to disable using transactions. [More details](https://orm.drizzle.team/docs/transactions) |
| `localesSuffix` | A string appended to the end of table names for storing localized fields. Default is '_locales'. |
| `relationshipsSuffix` | A string appended to the end of table names for storing relationships. Default is '_rels'. |
| `versionsSuffix` | A string appended to the end of table names for storing versions. Defaults to '_v'. |
## Access to Drizzle
After Payload is initialized, this adapter will expose the full power of Drizzle to you for use if you need it.
You can access Drizzle as follows:
```text
payload.db.drizzle
```
## Tables and relations
In addition to exposing Drizzle directly, all of the tables and Drizzle relations are exposed for you via the `payload.db` property as well.
- Tables - `payload.db.tables`
- Relations - `payload.db.relations`
## Prototyping in development mode
Drizzle exposes two ways to work locally in development mode.
The first is [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push), which automatically pushes changes you make to your Payload Config (and therefore, Drizzle schema) to your database so you don't have to manually migrate every time you change your Payload Config. This only works in development mode, and should not be mixed with manually running [`migrate`](/docs/database/migrations) commands.
You will be warned if any changes that you make will entail data loss while in development mode. Push is enabled by default, but you can opt out if you'd like.
Alternatively, you can disable `push` and rely solely on migrations to keep your local database in sync with your Payload Config.
## Migration workflows
In SQLite, migrations are a fundamental aspect of working with Payload and you should become familiar with how they work.
For more information about migrations, [click here](/docs/beta/database/migrations#when-to-run-migrations).

View File

@@ -68,3 +68,7 @@ The following functions can be used for managing transactions:
`payload.db.beginTransaction` - Starts a new session and returns a transaction ID for use in other Payload Local API calls.
`payload.db.commitTransaction` - Takes the identifier for the transaction, finalizes any changes.
`payload.db.rollbackTransaction` - Takes the identifier for the transaction, discards any changes.
## Disabling Transactions
If you wish to disable transactions entirely, you can do so by passing `false` as the `transactionOptions` in your database adapter configuration. All the official Payload database adapters support this option.

View File

@@ -10,7 +10,7 @@ keywords: email, overview, config, configuration, documentation, Content Managem
Payload has a few email adapters that can be imported to enable email functionality. The [@payloadcms/email-nodemailer](https://www.npmjs.com/package/@payloadcms/email-nodemailer) package will be the package most will want to install. This package provides an easy way to use [Nodemailer](https://nodemailer.com) for email and won't get in your way for those already familiar.
The email adapter should be passed into the `email` property of the Payload Config. This will allow Payload to send emails for things like password resets, new user verification, and any other email sending needs you may have.
The email adapter should be passed into the `email` property of the Payload Config. This will allow Payload to send [auth-related emails](../authentication/email) for things like password resets, new user verification, and any other email sending needs you may have.
## Configuration

View File

@@ -2,14 +2,17 @@
title: Array Field
label: Array
order: 20
desc: Array fields are intended for sets of repeating fields, that you define. Learn how to use array fields, see examples and options.
desc: Array Fields are intended for sets of repeating fields, that you define. Learn how to use Array Fields, see examples and options.
keywords: array, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Array field type is used when you need to have a set of "repeating" fields. It stores an array
of objects containing the fields that you define. Its uses can be simple or highly complex.
</Banner>
The Array Field is used when you need to have a set of "repeating" [Fields](./overview). It stores an array of objects containing fields that you define. These fields can be of any type, including other arrays to achieve infinitely nested structures.
Arrays are useful for many different types of content from simple to complex, such as:
- A "slider" with an image ([upload field](/docs/fields/upload)) and a caption ([text field](/docs/fields/text))
- Navigational structures where editors can specify nav items containing pages ([relationship field](/docs/fields/relationship)), an "open in new tab" [checkbox field](/docs/fields/checkbox)
- Event agenda "timeslots" where you need to specify start & end time ([date field](/docs/fields/date)), label ([text field](/docs/fields/text)), and Learn More page [relationship](/docs/fields/relationship)
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/array.png"
@@ -18,13 +21,23 @@ keywords: array, fields, config, configuration, documentation, Content Managemen
caption="Admin Panel screenshot of an Array field with two Rows"
/>
**Example uses:**
To create an Array Field, set the `type` to `array` in your [Field Config](./overview):
- A "slider" with an image ([upload field](/docs/fields/upload)) and a caption ([text field](/docs/fields/text))
- Navigational structures where editors can specify nav items containing pages ([relationship field](/docs/fields/relationship)), an "open in new tab" [checkbox field](/docs/fields/checkbox)
- Event agenda "timeslots" where you need to specify start & end time ([date field](/docs/fields/date)), label ([text field](/docs/fields/text)), and Learn More page [relationship](/docs/fields/relationship)
```ts
import type { Field } from 'payload/types'
## Config
export const MyArrayField: Field = {
// ...
// highlight-start
type: 'array',
fields: [
// ...
],
// highlight-end
}
```
## Config Options
| Option | Description |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -34,7 +47,7 @@ keywords: array, fields, config, configuration, documentation, Content Managemen
| **`validate`** | Provide a custom validation function that will be executed on both the [Admin Panel](../admin/overview) and the backend. [More](/docs/fields/overview#validation) |
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. |
| **`maxRows`** | A number for the most allowed items during validation when a value is present. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
@@ -42,7 +55,7 @@ keywords: array, fields, config, configuration, documentation, Content Managemen
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this Array will be kept, so there is no need to specify each nested field as `localized`. |
| **`required`** | Require this field to have a value. |
| **`labels`** | Customize the row labels appearing in the Admin dashboard. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). |
| **`dbName`** | Custom table name for the field when using SQL Database Adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
@@ -50,9 +63,22 @@ keywords: array, fields, config, configuration, documentation, Content Managemen
_\* An asterisk denotes that a property is required._
## Admin Config
## Admin Options
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can adjust the following properties:
The customize the appearance and behavior of the Array Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
```ts
import type { Field } from 'payload/types'
export const MyArrayField: Field = {
// ...
admin: { // highlight-line
// ...
},
}
```
The Array Field inherits all of the default options from the base [Field Admin Config](../admin/fields#admin-options), plus the following additional options:
| Option | Description |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------- |
@@ -62,7 +88,7 @@ In addition to the default [field admin config](/docs/fields/overview#admin-conf
## Example
`collections/ExampleCollection.ts`
In this example, we have an Array Field called `slider` that contains a set of fields for a simple image slider. Each row in the array has a `title`, `image`, and `caption`. We also customize the row label to display the title if it exists, or a default label if it doesn't.
```ts
import { CollectionConfig } from 'payload'

View File

@@ -2,16 +2,17 @@
title: Blocks Field
label: Blocks
order: 30
desc: The Blocks field type is a great layout build and can be used to construct any flexible content model. Learn how to use Block fields, see examples and options.
desc: The Blocks Field is a great layout build and can be used to construct any flexible content model. Learn how to use Block Fields, see examples and options.
keywords: blocks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Blocks field type is <strong>incredibly powerful</strong> and can be used as a{' '}
<em>layout builder</em> as well as to define any other flexible content model you can think of. It
stores an array of objects, where each object must match the shape of one of your provided block
configs.
</Banner>
The Blocks Field is <strong>incredibly powerful</strong>, storing an array of objects based on the fields that your define, where each item in the array is a "block" with its own unique schema.
Blocks are a great way to create a flexible content model that can be used to build a wide variety of content types, including:
- A layout builder tool that grants editors to design highly customizable page or post layouts. Blocks could include configs such as `Quote`, `CallToAction`, `Slider`, `Content`, `Gallery`, or others.
- A form builder tool where available block configs might be `Text`, `Select`, or `Checkbox`.
- Virtual event agenda "timeslots" where a timeslot could either be a `Break`, a `Presentation`, or a `BreakoutSession`.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/blocks.png"
@@ -20,13 +21,23 @@ keywords: blocks, fields, config, configuration, documentation, Content Manageme
caption="Admin Panel screenshot of add Blocks drawer view"
/>
**Example uses:**
To add a Blocks Field, set the `type` to `blocks` in your [Field Config](./overview):
- A layout builder tool that grants editors to design highly customizable page or post layouts. Blocks could include configs such as `Quote`, `CallToAction`, `Slider`, `Content`, `Gallery`, or others.
- A form builder tool where available block configs might be `Text`, `Select`, or `Checkbox`.
- Virtual event agenda "timeslots" where a timeslot could either be a `Break`, a `Presentation`, or a `BreakoutSession`.
```ts
import type { Field } from 'payload/types'
## Field config
export const MyBlocksField: Field = {
// ...
// highlight-start
type: 'blocks',
blocks: [
// ...
],
// highlight-end
}
```
## Config Options
| Option | Description |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -36,7 +47,7 @@ keywords: blocks, fields, config, configuration, documentation, Content Manageme
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. |
| **`maxRows`** | A number for the most allowed items during validation when a value is present. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API response or the Admin Panel. |
@@ -44,22 +55,35 @@ keywords: blocks, fields, config, configuration, documentation, Content Manageme
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this field will be kept, so there is no need to specify each nested field as `localized`. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`labels`** | Customize the block row labels appearing in the Admin dashboard. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
_\* An asterisk denotes that a property is required._
## Admin Config
## Admin Options
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can adjust the following properties:
The customize the appearance and behavior of the Blocks Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
```ts
import type { Field } from 'payload/types'
export const MyBlocksField: Field = {
// ...
admin: { // highlight-line
// ...
},
}
```
The Blocks Field inherits all of the default options from the base [Field Admin Config](../admin/fields#admin-options), plus the following additional options:
| Option | Description |
| ------------------- | ---------------------------------- |
| **`initCollapsed`** | Set the initial collapsed state |
| **`isSortable`** | Disable order sorting by setting this value to `false` |
## Block configs
## Block Configs
Blocks are defined as separate configs of their own.

View File

@@ -6,7 +6,7 @@ desc: Checkbox field types allow the developer to save a boolean value in the da
keywords: checkbox, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>The Checkbox field type saves a boolean in the database.</Banner>
The Checkbox Field saves a boolean in the database.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/checkbox.png"
@@ -15,7 +15,18 @@ keywords: checkbox, fields, config, configuration, documentation, Content Manage
caption="Admin Panel screenshot of Checkbox field with Text field below"
/>
## Config
To add a Checkbox Field, set the `type` to `checkbox` in your [Field Config](./overview):
```ts
import type { Field } from 'payload/types'
export const MyCheckboxField: Field = {
// ...
type: 'checkbox', // highlight-line
}
```
## Config Options
| Option | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -23,14 +34,14 @@ keywords: checkbox, fields, config, configuration, documentation, Content Manage
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide data to be used for this field's default value, will default to false if field is also `required`. [More](/docs/fields/overview#default-values) |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
| **`admin`** | Admin-specific configuration. [More details](../admin/fields#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
@@ -38,7 +49,7 @@ _\* An asterisk denotes that a property is required._
## Example
`collections/ExampleCollection.ts`
Here is an example of a Checkbox Field in a Collection:
```ts
import { CollectionConfig } from 'payload'

View File

@@ -7,21 +7,27 @@ desc: The Code field type will store any string in the Database. Learn how to us
keywords: code, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Code field type saves a string in the database, but provides the Admin Panel with a code
editor styled interface.
</Banner>
The Code Field saves a string in the database, but provides the [Admin Panel](../admin/overview) with a code editor styled interface.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/code.png"
srcDark="https://payloadcms.com/images/docs/fields/code-dark.png"
alt="Shows a Code field in the Payload Admin Panel"
caption="Admin Panel screenshot of a Code field"
caption="This field is using the `monaco-react` editor syntax highlighting."
/>
This field uses the `monaco-react` editor syntax highlighting.
To add a Code Field, set the `type` to `code` in your [Field Config](./overview):
## Config
```ts
import type { Field } from 'payload/types'
export const MyBlocksField: Field = {
// ...
type: 'code', // highlight-line
}
```
## Config Options
| Option | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -32,22 +38,35 @@ This field uses the `monaco-react` editor syntax highlighting.
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
_\* An asterisk denotes that a property is required._
## Admin Config
## Admin Options
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can adjust the following properties:
The customize the appearance and behavior of the Code Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
```ts
import type { Field } from 'payload/types'
export const MyCodeField: Field = {
// ...
admin: { // highlight-line
// ...
},
}
```
The Code Field inherits all of the default options from the base [Field Admin Config](../admin/fields#admin-options), plus the following additional options:
| Option | Description |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

View File

@@ -6,10 +6,7 @@ desc: With the Collapsible field, you can place fields within a collapsible layo
keywords: row, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Collapsible field is presentational-only and only affects the Admin Panel. By using it, you
can place fields within a nice layout component that can be collapsed / expanded.
</Banner>
The Collapsible Field is presentational-only and only affects the Admin Panel. By using it, you can place fields within a nice layout component that can be collapsed / expanded.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/collapsible.png"
@@ -18,20 +15,49 @@ keywords: row, fields, config, configuration, documentation, Content Management
caption="Admin Panel screenshot of a Collapsible field"
/>
## Config
To add a Collapsible Field, set the `type` to `collapsible` in your [Field Config](./overview):
```ts
import type { Field } from 'payload/types'
export const MyCollapsibleField: Field = {
// ...
// highlight-start
type: 'collapsible',
fields: [
// ...
],
// highlight-end
}
```
## Config Options
| Option | Description |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`label`** \* | A label to render within the header of the collapsible component. This can be a string, function or react component. Function/components receive `({ data, path })` as args. |
| **`fields`** \* | Array of field types to nest within this Collapsible. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
_\* An asterisk denotes that a property is required._
## Admin Config
## Admin Options
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can adjust the following properties:
The customize the appearance and behavior of the Collapsible Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
```ts
import type { Field } from 'payload/types'
export const MyCollapsibleField: Field = {
// ...
admin: { // highlight-line
// ...
},
}
```
The Collapsible Field inherits all of the default options from the base [Field Admin Config](../admin/fields#admin-options), plus the following additional options:
| Option | Description |
| ------------------- | ------------------------------- |

View File

@@ -6,21 +6,27 @@ desc: The Date field type stores a Date in the database. Learn how to use and cu
keywords: date, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Date field type saves a Date in the database and provides the Admin Panel with a customizable
time picker interface.
</Banner>
The Date Field saves a Date in the database and provides the [Admin Panel](../admin/overview) with a customizable time picker interface.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/date.png"
srcDark="https://payloadcms.com/images/docs/fields/date-dark.png"
alt="Shows a Date field in the Payload Admin Panel"
caption="Admin Panel screenshot of a Date field"
caption="This field is using the `react-datepicker` component for UI."
/>
This field uses [`react-datepicker`](https://www.npmjs.com/package/react-datepicker) for the Admin Panel component.
To add a Date Field, set the `type` to `date` in your [Field Config](./overview):
## Config
```ts
import type { Field } from 'payload/types'
export const MyDateField: Field = {
// ...
type: 'date', // highlight-line
}
```
## Config Options
| Option | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -28,22 +34,35 @@ This field uses [`react-datepicker`](https://www.npmjs.com/package/react-datepic
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
_\* An asterisk denotes that a property is required._
## Admin Config
## Admin Options
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can customize the following fields that will adjust how the component displays in the Admin Panel via the `date` property.
The customize the appearance and behavior of the Date Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
```ts
import type { Field } from 'payload/types'
export const MyDateField: Field = {
// ...
admin: { // highlight-line
// ...
},
}
```
The Date Field inherits all of the default options from the base [Field Admin Config](../admin/fields#admin-options), plus the following additional options:
| Property | Description |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |

View File

@@ -6,7 +6,7 @@ desc: The Email field enforces that the value provided is a valid email address.
keywords: email, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>The Email field enforces that the value provided is a valid email address.</Banner>
The Email Field enforces that the value provided is a valid email address.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/email.png"
@@ -15,7 +15,18 @@ keywords: email, fields, config, configuration, documentation, Content Managemen
caption="Admin Panel screenshot of an Email field"
/>
## Config
To create an Email Field, set the `type` to `email` in your [Field Config](./overview):
```ts
import type { Field } from 'payload/types'
export const MyEmailField: Field = {
// ...
type: 'email', // highlight-line
}
```
## Config Options
| Option | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -24,30 +35,40 @@ keywords: email, fields, config, configuration, documentation, Content Managemen
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
_\* An asterisk denotes that a property is required._
## Admin config
## Admin Options
In addition to the default [field admin config](/docs/fields/overview#admin-config), this field type allows for the following `admin` properties:
The customize the appearance and behavior of the Email Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
**`placeholder`**
```ts
import type { Field } from 'payload/types'
Set this property to define a placeholder string for the field.
export const MyEmailField: Field = {
// ...
admin: { // highlight-line
// ...
},
}
```
**`autoComplete`**
The Email Field inherits all of the default options from the base [Field Admin Config](../admin/fields#admin-options), plus the following additional options:
Set this property to a string that will be used for browser autocomplete.
| Property | Description |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| **`placeholder`** | Set this property to define a placeholder string for the field. |
| **`autoComplete`** | Set this property to a string that will be used for browser autocomplete. |
## Example

View File

@@ -6,10 +6,7 @@ desc: The Group field allows other fields to be nested under a common property.
keywords: group, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Group field allows fields to be nested under a common property name. It also groups fields
together visually in the Admin Panel.
</Banner>
The Group Field allows [Fields](./overview) to be nested under a common property name. It also groups fields together visually in the [Admin Panel](../admin/overview).
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/group.png"
@@ -18,7 +15,23 @@ keywords: group, fields, config, configuration, documentation, Content Managemen
caption="Admin Panel screenshot of a Group field"
/>
## Config
To add a Group Field, set the `type` to `group` in your [Field Config](./overview):
```ts
import type { Field } from 'payload/types'
export const MyGroupField: Field = {
// ...
// highlight-start
type: 'group',
fields: [
// ...
],
// highlight-end
}
```
## Config Options
| Option | Description |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -26,26 +39,39 @@ keywords: group, fields, config, configuration, documentation, Content Managemen
| **`fields`** \* | Array of field types to nest within this Group. |
| **`label`** | Used as a heading in the Admin Panel and to name the generated GraphQL type. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide an object of data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this Group will be kept, so there is no need to specify each nested field as `localized`. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
_\* An asterisk denotes that a property is required._
## Admin config
## Admin Options
In addition to the default [field admin config](/docs/fields/overview#admin-config), the Group allows for the following admin property:
The customize the appearance and behavior of the Group Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
**`hideGutter`**
```ts
import type { Field } from 'payload/types'
Set this property to `true` to hide this field's gutter within the Admin Panel. The field gutter is rendered as a vertical line and padding, but often if this field is nested within a Group, Block, or Array, you may want to hide the gutter.
export const MyGroupField: Field = {
// ...
admin: { // highlight-line
// ...
},
}
```
The Group Field inherits all of the default options from the base [Field Admin Config](../admin/fields#admin-options), plus the following additional options:
| Option | Description |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`hideGutter`** | Set this property to `true` to hide this field's gutter within the Admin Panel. The field gutter is rendered as a vertical line and padding, but often if this field is nested within a Group, Block, or Array, you may want to hide the gutter. |
## Example

View File

@@ -7,21 +7,27 @@ desc: The JSON field type will store any string in the Database. Learn how to us
keywords: json, jsonSchema, schema, validation, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The JSON field type saves actual JSON in the database, which differs from the Code field that
saves the value as a string in the database.
</Banner>
The JSON Field saves actual JSON in the database, which differs from the Code field that saves the value as a string in the database.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/json.png"
srcDark="https://payloadcms.com/images/docs/fields/json-dark.png"
alt="Shows a JSON field in the Payload Admin Panel"
caption="Admin Panel screenshot of a JSON field"
caption="This field is using the `monaco-react` editor syntax highlighting."
/>
This field uses the `monaco-react` editor syntax highlighting.
To add a JSON Field, set the `type` to `json` in your [Field Config](./overview):
## Config
```ts
import type { Field } from 'payload/types'
export const MyJSONField: Field = {
// ...
type: 'json', // highlight-line
}
```
## Config Options
| Option | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -31,22 +37,35 @@ This field uses the `monaco-react` editor syntax highlighting.
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`jsonSchema`** | Provide a JSON schema that will be used for validation. [JSON schemas](https://json-schema.org/learn/getting-started-step-by-step) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
_\* An asterisk denotes that a property is required._
## Admin Config
## Admin Options
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can adjust the following properties:
The customize the appearance and behavior of the JSON Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
```ts
import type { Field } from 'payload/types'
export const MyJSONField: Field = {
// ...
admin: { // highlight-line
// ...
},
}
```
The JSON Field inherits all of the default options from the base [Field Admin Config](../admin/fields#admin-options), plus the following additional options:
| Option | Description |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |

View File

@@ -6,10 +6,7 @@ desc: Number fields store and validate numeric data. Learn how to use and format
keywords: number, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Number field stores and validates numeric entry and supports additional numerical validation
and formatting features.
</Banner>
The Number Field stores and validates numeric entry and supports additional numerical validation and formatting features.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/number.png"
@@ -18,7 +15,18 @@ keywords: number, fields, config, configuration, documentation, Content Manageme
caption="Admin Panel screenshot of a Number field"
/>
## Config
To add a Number Field, set the `type` to `number` in your [Field Config](./overview):
```ts
import type { Field } from 'payload/types'
export const MyNumberField: Field = {
// ...
type: 'number', // highlight-line
}
```
## Config Options
| Option | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -32,34 +40,41 @@ keywords: number, fields, config, configuration, documentation, Content Manageme
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
_\* An asterisk denotes that a property is required._
## Admin config
## Admin Options
In addition to the default [field admin config](/docs/fields/overview#admin-config), this field type allows for the following `admin` properties:
The customize the appearance and behavior of the Number Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
**`step`**
```ts
import type { Field } from 'payload/types'
Set a value for the number field to increment / decrement using browser controls.
export const MyNumberField: Field = {
// ...
admin: { // highlight-line
// ...
},
}
```
**`placeholder`**
The Number Field inherits all of the default options from the base [Field Admin Config](../admin/fields#admin-options), plus the following additional options:
Set this property to define a placeholder string for the field.
**`autoComplete`**
Set this property to a string that will be used for browser autocomplete.
| Property | Description |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| **`step`** | Set a value for the number field to increment / decrement using browser controls. |
| **`placeholder`** | Set this property to define a placeholder string for the field. |
| **`autoComplete`** | Set this property to a string that will be used for browser autocomplete. |
## Example

View File

@@ -205,7 +205,9 @@ export const MyField: Field = {
}
```
Default values can be defined as a static string or a function that returns a string. Functions are called with the following arguments:
Default values can be defined as a static value or a function that returns a value. When a `defaultValue` is defined statically, Payload's DB adapters will apply it to the database schema or models.
Functions can be written to make use of the following argument properties:
- `user` - the authenticated user object
- `locale` - the currently selected locale string
@@ -294,7 +296,7 @@ When using custom validation functions, Payload will use yours in place of the d
To reuse default field validations, call them from within your custom validation function:
```ts
import { text } from 'payload/fields/validations'
import { text } from 'payload/shared'
const field: Field = {
name: 'notBad',
@@ -375,6 +377,8 @@ export const MyCollection: CollectionConfig = {
<Banner type="warning">
<strong>Reminder:</strong>
The Custom ID Fields can only be of type [`Number`](./number) or [`Text`](./text).
Custom ID fields with type `text` must not contain `/` or `.` characters.
</Banner>
## TypeScript

View File

@@ -3,18 +3,10 @@ title: Point Field
label: Point
order: 110
desc: The Point field type stores coordinates in the database. Learn how to use Point field for geolocation and geometry.
keywords: point, geolocation, geospatial, geojson, 2dsphere, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Point field type saves a pair of coordinates in the database and assigns an index for location
related queries.
</Banner>
<Banner type="warning">
<strong>Note:</strong> The Point field type is currently only supported in MongoDB.
</Banner>
The Point Field saves a pair of coordinates in the database and assigns an index for location related queries. The data structure in the database matches the GeoJSON structure to represent point. The Payload APIs simplifies the object data to only the [longitude, latitude] location.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/point.png"
@@ -23,7 +15,21 @@ keywords: point, geolocation, geospatial, geojson, 2dsphere, config, configurati
caption="Admin Panel screenshot of a Point field"
/>
The data structure in the database matches the GeoJSON structure to represent point. The Payload APIs simplifies the object data to only the [longitude, latitude] location.
To add a Point Field, set the `type` to `point` in your [Field Config](./overview):
```ts
import type { Field } from 'payload/types'
export const MyPointField: Field = {
// ...
type: 'point', // highlight-line
}
```
<Banner type="warning">
<strong>Important:</strong>
The Point Field is currently only supported in MongoDB.
</Banner>
## Config
@@ -34,23 +40,19 @@ The data structure in the database matches the GeoJSON structure to represent po
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. To support location queries, point index defaults to `2dsphere`, to disable the index set to `false`. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
| **`admin`** | Admin-specific configuration. [More details](../admin/fields#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
_\* An asterisk denotes that a property is required._
<Banner type="warning">
<strong>Note:</strong> The Point field type is currently only supported in MongoDB.
</Banner>
## Example
`collections/ExampleCollection.ts`

View File

@@ -6,10 +6,7 @@ desc: The Radio field type allows for the selection of one value from a predefin
keywords: radio, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Radio Group field type allows for the selection of one value from a predefined set of possible
values and presents a radio group-style set of inputs to the Admin Panel.
</Banner>
The Radio Field allows for the selection of one value from a predefined set of possible values and presents a radio group-style set of inputs to the [Admin Panel](../admin/overview).
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/radio.png"
@@ -18,7 +15,23 @@ keywords: radio, fields, config, configuration, documentation, Content Managemen
caption="Admin Panel screenshot of a Radio field"
/>
## Config
To add a Radio Field, set the `type` to `radio` in your [Field Config](./overview):
```ts
import type { Field } from 'payload/types'
export const MyRadioField: Field = {
// ...
// highlight-start
type: 'radio',
options: [
// ...
]
// highlight-end
}
```
## Config Options
| Option | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -27,14 +40,14 @@ keywords: radio, fields, config, configuration, documentation, Content Managemen
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. The default value must exist within provided values in `options`. [More](/docs/fields/overview#default-values) |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`enumName`** | Custom enum name for this field when using SQL Database Adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
@@ -50,13 +63,26 @@ _\* An asterisk denotes that a property is required._
being used as a GraphQL enum.
</Banner>
## Admin config
## Admin Options
In addition to the default [field admin config](/docs/fields/overview#admin-config), the Radio Group field type allows for the specification of the following `admin` properties:
The customize the appearance and behavior of the Radio Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
**`layout`**
```ts
import type { Field } from 'payload/types'
The `layout` property allows for the radio group to be styled as a horizonally or vertically distributed list. The default value is `horizontal`.
export const MyRadioField: Field = {
// ...
admin: { // highlight-line
// ...
},
}
```
The Radio Field inherits all of the default options from the base [Field Admin Config](../admin/fields#admin-options), plus the following additional options:
| Property | Description |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| **`layout`** | Allows for the radio group to be styled as a horizonally or vertically distributed list. The default value is `horizontal`. |
## Example

View File

@@ -6,10 +6,7 @@ desc: The Relationship field provides the ability to relate documents together.
keywords: relationship, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Relationship field is one of the most powerful fields Payload features. It provides for the
ability to easily relate documents together.
</Banner>
The Relationship Field is one of the most powerful fields Payload features. It provides for the ability to easily relate documents together.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/relationship.png"
@@ -18,13 +15,27 @@ keywords: relationship, fields, config, configuration, documentation, Content Ma
caption="Admin Panel screenshot of a Relationship field"
/>
**Example uses:**
The Relationship field is used in a variety of ways, including:
- To add `Product` documents to an `Order` document
- To allow for an `Order` to feature a `placedBy` relationship to either an `Organization` or `User` collection
- To assign `Category` documents to `Post` documents
## Config
To add a Relationship Field, set the `type` to `relationship` in your [Field Config](./overview):
```ts
import type { Field } from 'payload/types'
export const MyRelationshipField: Field = {
// ...
// highlight-start
type: 'relationship',
relationTo: 'products',
// highlight-end
}
```
## Config Options
| Option | Description |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -39,14 +50,14 @@ keywords: relationship, fields, config, configuration, documentation, Content Ma
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
@@ -54,30 +65,33 @@ _\* An asterisk denotes that a property is required._
<Banner type="success">
<strong>Tip:</strong>
<br />
The [Depth](../queries/depth) parameter can be used to automatically populate
related documents that are returned by the API.
The [Depth](../queries/depth) parameter can be used to automatically populate related documents that are returned by the API.
</Banner>
## Admin config
## Admin Options
In addition to the default [field admin config](/docs/fields/overview#admin-config), the Relationship field type also
allows for the following admin-specific properties:
The customize the appearance and behavior of the Relationship Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
**`isSortable`**
```ts
import type { Field } from 'payload/types'
Set to `true` if you'd like this field to be sortable within the Admin UI using drag and drop (only works when `hasMany`
is set to `true`).
export const MyRelationshipField: Field = {
// ...
admin: { // highlight-line
// ...
},
}
```
**`allowCreate`**
The Relationship Field inherits all of the default options from the base [Field Admin Config](../admin/fields#admin-options), plus the following additional options:
Set to `false` if you'd like to disable the ability to create new documents from within the relationship field (hides
the "Add new" button in the admin UI).
| Property | Description |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **`isSortable`** | Set to `true` if you'd like this field to be sortable within the Admin UI using drag and drop (only works when `hasMany` is set to `true`). |
| **`allowCreate`** | Set to `false` if you'd like to disable the ability to create new documents from within the relationship field. |
| **`sortOptions`** | Define a default sorting order for the options within a Relationship field's dropdown. [More](#sortOptions) |
**`sortOptions`**
The `sortOptions` property allows you to define a default sorting order for the options within a Relationship field's
dropdown. This can be particularly useful for ensuring that the most relevant options are presented first to the user.
### Sort Options
You can specify `sortOptions` in two ways:
@@ -179,7 +193,7 @@ You can learn more about writing queries [here](/docs/queries/overview).
When a relationship field has both <strong>filterOptions</strong> and a custom{' '}
<strong>validate</strong> function, the api will not validate <strong>filterOptions</strong>{' '}
unless you call the default relationship field validation function imported from{' '}
<strong>payload/fields/validations</strong> in your validate function.
<strong>payload/shared</strong> in your validate function.
</Banner>
## How the data is saved

View File

@@ -6,10 +6,7 @@ desc: The Rich Text field allows dynamic content to be written through the Admin
keywords: rich text, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Rich Text field is a powerful way to allow editors to write dynamic content. The content is
saved as JSON in the database and can be converted into any format, including HTML, that you need.
</Banner>
The Rich Text Field is a powerful way to allow editors to write dynamic content. The content is saved as JSON in the database and can be converted into any format, including HTML, that you need.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/richtext.png"
@@ -39,43 +36,50 @@ Right now, Payload is officially supporting two rich text editors:
will allow you to apply your learnings elsewhere as well.
</Banner>
## Config
## Config Options
| Option | Description |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`editor`** | Override the rich text editor specified in your base configuration for this field. |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
_\* An asterisk denotes that a property is required._
## Admin config
## Admin Options
In addition to the default [field admin config](/docs/fields/overview#admin-config), the Rich Text editor allows for the following admin properties:
The customize the appearance and behavior of the Rich Text Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
**`placeholder`**
```ts
import type { Field } from 'payload/types'
Set this property to define a placeholder string in the text input.
export const MyRichTextField: Field = {
// ...
admin: { // highlight-line
// ...
},
}
```
**`hideGutter`**
The Rich Text Field inherits all of the default options from the base [Field Admin Config](../admin/fields#admin-options), plus the following additional options:
Set this property to `true` to hide this field's gutter within the Admin Panel. The field gutter is rendered as a vertical line and padding, but often if this field is nested within a Group, Block, or Array, you may want to hide the gutter.
| Property | Description |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| **`placeholder`** | Set this property to define a placeholder string for the field. |
| **`hideGutter`** | Set this property to `true` to hide this field's gutter within the Admin Panel. |
| **`rtl`** | Override the default text direction of the Admin Panel for this field. Set to `true` to force right-to-left text direction. |
**`rtl`**
Override the default text direction of the Admin Panel for this field. Set to `true` to force right-to-left text direction.
## Editor-specific options
## Editor-specific Options
For a ton more editor-specific options, including how to build custom rich text elements directly into your editor, take a look at either the [Slate docs](/docs/rich-text/slate) or the [Lexical docs](/docs/rich-text/lexical) depending on which editor you're using.

View File

@@ -6,10 +6,7 @@ desc: With the Row field you can arrange fields next to each other in the Admin
keywords: row, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Row field is presentational-only and only affects the Admin Panel. By using it, you can
arrange fields next to each other horizontally.
</Banner>
The Row Field is presentational-only and only affects the [Admin Panel](../admin/overview). By using it, you can arrange [Fields](./overview) next to each other horizontally.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/row.png"
@@ -18,12 +15,28 @@ keywords: row, fields, config, configuration, documentation, Content Management
caption="Admin Panel screenshot of a Row field"
/>
## Config
To add a Row Field, set the `type` to `row` in your [Field Config](./overview):
```ts
import type { Field } from 'payload/types'
export const MyRowField: Field = {
// ...
// highlight-start
type: 'row',
fields: [
// ...
]
// highlight-end
}
```
## Config Options
| Option | Description |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`fields`** \* | Array of field types to nest within this Row. |
| **`admin`** | Admin-specific configuration excluding `description`, `readOnly`, and `hidden`. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
| **`admin`** | Admin-specific configuration excluding `description`, `readOnly`, and `hidden`. [More details](../admin/fields#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
_\* An asterisk denotes that a property is required._

View File

@@ -6,10 +6,7 @@ desc: The Select field provides a dropdown-style interface for choosing options
keywords: select, multi-select, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Select field provides a dropdown-style interface for choosing options from a predefined list
as an enumeration.
</Banner>
The Select Field provides a dropdown-style interface for choosing options from a predefined list as an enumeration.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/select.png"
@@ -18,7 +15,23 @@ keywords: select, multi-select, fields, config, configuration, documentation, Co
caption="Admin Panel screenshot of a Select field"
/>
## Config
To add a Select Field, set the `type` to `select` in your [Field Config](./overview):
```ts
import type { Field } from 'payload/types'
export const MySelectField: Field = {
// ...
// highlight-start
type: 'select',
options: [
// ...
]
// highlight-end
}
```
## Config Options
| Option | Description |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -29,14 +42,14 @@ keywords: select, multi-select, fields, config, configuration, documentation, Co
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-options) for more details. |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`enumName`** | Custom enum name for this field when using SQL Database Adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
| **`dbName`** | Custom table name (if `hasMany` set to `true`) for this field when using SQL Database Adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
@@ -46,24 +59,33 @@ _\* An asterisk denotes that a property is required._
<Banner type="warning">
<strong>Important:</strong>
<br />
Option values should be strings that do not contain hyphens or special characters due to GraphQL
enumeration naming constraints. Underscores are allowed. If you determine you need your option
values to be non-strings or contain special characters, they will be formatted accordingly before
being used as a GraphQL enum.
</Banner>
## Admin config
## Admin Options
In addition to the default [field admin config](/docs/fields/overview#admin-config), the Select field type also allows for the following admin-specific properties:
The customize the appearance and behavior of the Select Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
**`isClearable`**
```ts
import type { Field } from 'payload/types'
Set to `true` if you'd like this field to be clearable within the Admin UI.
export const MySelectField: Field = {
// ...
admin: { // highlight-line
// ...
},
}
```
**`isSortable`**
The Select Field inherits all of the default options from the base [Field Admin Config](../admin/fields#admin-options), plus the following additional options:
Set to `true` if you'd like this field to be sortable within the Admin UI using drag and drop. (Only works when `hasMany` is set to `true`)
| Property | Description |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **`isClearable`** | Set to `true` if you'd like this field to be clearable within the Admin UI. |
| **`isSortable`** | Set to `true` if you'd like this field to be sortable within the Admin UI using drag and drop. (Only works when `hasMany` is set to `true`) |
## Example

View File

@@ -6,11 +6,7 @@ desc: The Tabs field is a great way to organize complex editing experiences into
keywords: tabs, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Tabs field is presentational-only and only affects the Admin Panel (unless a tab is named). By
using it, you can place fields within a nice layout component that separates certain sub-fields by
a tabbed interface.
</Banner>
The Tabs Field is presentational-only and only affects the [Admin Panel](../admin/overview) (unless a tab is named). By using it, you can place fields within a nice layout component that separates certain sub-fields by a tabbed interface.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/tabs.png"
@@ -19,12 +15,28 @@ keywords: tabs, fields, config, configuration, documentation, Content Management
caption="Tabs field type used to separate Hero fields from Page Layout"
/>
## Config
To add a Tabs Field, set the `type` to `tabs` in your [Field Config](./overview):
```ts
import type { Field } from 'payload/types'
export const MyTabsField: Field = {
// ...
// highlight-start
type: 'tabs',
tabs: [
// ...
]
// highlight-end
}
```
## Config Options
| Option | Description |
| ------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **`tabs`** \* | Array of tabs to render within this Tabs field. |
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
| **`admin`** | Admin-specific configuration. [More details](../admin/fields#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
### Tab-specific Config

View File

@@ -6,10 +6,7 @@ desc: Text field types simply save a string to the database and provide the Admi
keywords: text, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Text field type is one of the most commonly used fields. It saves a string to the database and
provides the Admin Panel with a simple text input.
</Banner>
The Text Field is one of the most commonly used fields. It saves a string to the database and provides the [Admin Panel](../admin/overview) with a simple text input.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/text.png"
@@ -18,7 +15,18 @@ keywords: text, fields, config, configuration, documentation, Content Management
caption="Admin Panel screenshot of a Text field and read-only Text field"
/>
## Config
To add a Text Field, set the `type` to `text` in your [Field Config](./overview):
```ts
import type { Field } from 'payload/types'
export const MyTextField: Field = {
// ...
type: 'text', // highlight-line
}
```
## Config Options
| Option | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -29,14 +37,14 @@ keywords: text, fields, config, configuration, documentation, Content Management
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`hasMany`** | Makes this field an ordered array of text instead of just a single text. |
| **`minRows`** | Minimum number of texts in the array, if `hasMany` is set to true. |
@@ -45,21 +53,28 @@ keywords: text, fields, config, configuration, documentation, Content Management
_\* An asterisk denotes that a property is required._
## Admin config
## Admin Options
In addition to the default [field admin config](/docs/fields/overview#admin-config), the Text field type allows for the following `admin` properties:
The customize the appearance and behavior of the Text Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
**`placeholder`**
```ts
import type { Field } from 'payload/types'
Set this property to define a placeholder string in the text input.
export const MyTextField: Field = {
// ...
admin: { // highlight-line
// ...
},
}
```
**`autoComplete`**
The Text Field inherits all of the default options from the base [Field Admin Config](../admin/fields#admin-options), plus the following additional options:
Set this property to a string that will be used for browser autocomplete.
**`rtl`**
Override the default text direction of the Admin Panel for this field. Set to `true` to force right-to-left text direction.
| Option | Description |
| -------------- | ---------------------------------------------------------------------------------------------------------------- |
| **`placeholder`** | Set this property to define a placeholder string in the text input. |
| **`autoComplete`** | Set this property to a string that will be used for browser autocomplete. |
| **`rtl`** | Override the default text direction of the Admin Panel for this field. Set to `true` to force right-to-left text direction. |
## Example

View File

@@ -6,10 +6,7 @@ desc: Textarea field types save a string to the database, similar to the Text fi
keywords: textarea, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Textarea field is almost identical to the Text field but it features a slightly larger input
that is better suited to edit longer text.
</Banner>
The Textarea Field is nearly identical to the [Text Field](./text) but it features a slightly larger input that is better suited to edit longer text.
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/textarea.png"
@@ -18,7 +15,18 @@ keywords: textarea, fields, config, configuration, documentation, Content Manage
caption="Admin Panel screenshot of a Textarea field and read-only Textarea field"
/>
## Config
To add a Textarea Field, set the `type` to `textarea` in your [Field Config](./overview):
```ts
import type { Field } from 'payload/types'
export const MyTextareaField: Field = {
// ...
type: 'textarea', // highlight-line
}
```
## Config Options
| Option | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -29,34 +37,41 @@ keywords: textarea, fields, config, configuration, documentation, Content Manage
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
_\* An asterisk denotes that a property is required._
## Admin config
## Admin Options
In addition to the default [field admin config](/docs/fields/overview#admin-config), the Textarea field type allows for the following `admin` properties:
The customize the appearance and behavior of the Textarea Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
**`placeholder`**
```ts
import type { Field } from 'payload/types'
Set this property to define a placeholder string in the textarea.
export const MyTextareaField: Field = {
// ...
admin: { // highlight-line
// ...
},
}
```
**`autoComplete`**
The Textarea Field inherits all of the default options from the base [Field Admin Config](../admin/fields#admin-options), plus the following additional options:
Set this property to a string that will be used for browser autocomplete.
**`rtl`**
Override the default text direction of the Admin Panel for this field. Set to `true` to force right-to-left text direction.
| Option | Description |
| -------------- | ---------------------------------------------------------------------------------------------------------------- |
| **`placeholder`** | Set this property to define a placeholder string in the textarea. |
| **`autoComplete`** | Set this property to a string that will be used for browser autocomplete. |
| **`rtl`** | Override the default text direction of the Admin Panel for this field. Set to `true` to force right-to-left text direction. |
## Example

View File

@@ -6,31 +6,34 @@ desc: UI fields are purely presentational and allow developers to customize the
keywords: custom field, react component, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The UI (user interface) field gives you a ton of power to add your own React components directly
into the Admin Panel, nested directly within your other fields. It has absolutely no effect on the
data of your documents. It is presentational-only.
</Banner>
The UI (user interface) Field gives you a ton of power to add your own React components directly into the [Admin Panel](../admin/overview), nested directly within your other fields. It has absolutely no effect on the data of your documents. It is presentational-only. Think of it as a way for you to "plug in" your own React components directly within your other fields, so you can provide your editors with new controls exactly where you want them to go.
This field is helpful if you need to build in custom functionality via React components within the Admin Panel. Think of it as a way for you to "plug in" your own React components directly within your other fields, so you can provide your editors with new controls exactly where you want them to go.
With this field, you can also inject custom `Cell` components that appear as additional columns within collections' List views.
**Example uses:**
With the UI Field, you can:
- Add a custom message or block of text within the body of an Edit View to describe the purpose of surrounding fields
- Add a "Refund" button to an Order's Edit View sidebar, which might make a fetch call to a custom `refund` endpoint
- Add a "view page" button into a Pages List View to give editors a shortcut to view a page on the frontend of the site
- Build a "clear cache" button or similar mechanism to manually clear caches of specific documents
## Config
To add a UI Field, set the `type` to `ui` in your [Field Config](./overview):
```ts
import type { Field } from 'payload/types'
export const MyUIField: Field = {
// ...
type: 'ui', // highlight-line
}
```
## Config Options
| Option | Description |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | A unique identifier for this field. |
| **`label`** | Human-readable label for this UI field. |
| **`admin.components.Field`** \* | React component to be rendered for this field within the Edit View. [More](/docs/admin/components/#field-component) |
| **`admin.components.Cell`** | React component to be rendered as a Cell within collection List views. [More](/docs/admin/components/#field-component) |
| **`admin.components.Field`** \* | React component to be rendered for this field within the Edit View. [More](../admin/components/#field-component) |
| **`admin.components.Cell`** | React component to be rendered as a Cell within collection List views. [More](../admin/components/#field-component) |
| **`admin.disableListColumn`** | Set `disableListColumn` to `true` to prevent the UI field from appearing in the list view column selector. |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
@@ -51,8 +54,8 @@ export const ExampleCollection: CollectionConfig = {
type: 'ui', // required
admin: {
components: {
Field: MyCustomUIField,
Cell: MyCustomUICell,
Field: '/path/to/MyCustomUIField',
Cell: '/path/to/MyCustomUICell',
},
},
},

View File

@@ -6,18 +6,13 @@ desc: Upload fields will allow a file to be uploaded, only from a collection sup
keywords: upload, images media, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
The Upload field allows for the selection of a Document from a collection supporting Uploads, and
formats the selection as a thumbnail in the Admin Panel.
</Banner>
The Upload Field allows for the selection of a Document from a Collection supporting [Uploads](../upload/overview), and formats the selection as a thumbnail in the Admin Panel.
<Banner type="warning">
<strong>Important:</strong>
<br />
To use this field, you need to have a Collection configured to allow Uploads. For more
information, [click here](/docs/upload/overview) to read about how to enable Uploads on a
collection by collection basis.
</Banner>
Upload fields are useful for a variety of use cases, such as:
- To provide a `Page` with a featured image
- To allow for a `Product` to deliver a downloadable asset like PDF or MP3
- To give a layout building block the ability to feature a background image
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/fields/upload.png"
@@ -26,13 +21,26 @@ keywords: upload, images media, fields, config, configuration, documentation, Co
caption="Admin Panel screenshot of an Upload field"
/>
**Example uses:**
To create an Upload Field, set the `type` to `upload` in your [Field Config](./overview):
- To provide a `Page` with a featured image
- To allow for a `Product` to deliver a downloadable asset like PDF or MP3
- To give a layout building block the ability to feature a background image
```ts
import type { Field } from 'payload/types'
## Config
export const MyUploadField: Field = {
// ...
// highlight-start
type: 'upload',
relationTo: 'media',
// highlight-end
}
```
<Banner type="warning">
<strong>Important:</strong>
To use the Upload Field, you must have a [Collection](../configuration/collections) configured to allow [Uploads](../upload/overview).
</Banner>
## Config Options
| Option | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -44,14 +52,15 @@ keywords: upload, images media, fields, config, configuration, documentation, Co
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
| **`displayPreview`** | Enable displaying preview of the uploaded file. Overrides related Collection's `displayPreview` option. [More](/docs/upload/overview#collection-upload-options). |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
| **`admin`** | Admin-specific configuration. [Admin Options](../admin/fields#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
@@ -115,5 +124,5 @@ You can learn more about writing queries [here](/docs/queries/overview).
When an upload field has both <strong>filterOptions</strong> and a custom{' '}
<strong>validate</strong> function, the api will not validate <strong>filterOptions</strong>{' '}
unless you call the default upload field validation function imported from{' '}
<strong>payload/fields/validations</strong> in your validate function.
<strong>payload/shared</strong> in your validate function.
</Banner>

View File

@@ -18,11 +18,11 @@ Payload is database agnostic, meaning you can use any type of database behind Pa
## Collections
A Collection is a group of records, called Documents, that all share a common schema. Each Collection saves to the [Database](../database/overview) based on the [Fields](../fields/overview) that you define. [More details](../configuration/collections).
A Collection is a group of records, called Documents, that all share a common schema. Each Collection is stored in the [Database](../database/overview) based on the [Fields](../fields/overview) that you define. [More details](../configuration/collections).
## Globals
Globals are in many ways similar to [Collections](../configuration/collections), except they correspond to only a single Document. Each Global saves to the [Database](../database/overview) based on the [Fields](../fields/overview) that you define. [More details](../configuration/globals).
Globals are in many ways similar to [Collections](../configuration/collections), except they correspond to only a single Document. Each Global is stored in the [Database](../database/overview) based on the [Fields](../fields/overview) that you define. [More details](../configuration/globals).
## Fields
@@ -30,23 +30,23 @@ Fields are the building blocks of Payload. They define the schema of the Documen
## Hooks
Hooks allow you to execute your own logic during specific events of the Document lifecycle, such as read or update. [More details](../hooks/overview).
Hooks allow you to execute your own side effects during specific events of the Document lifecycle, such as before read, after create, etc. [More details](../hooks/overview).
## Authentication
Payload provides a secure, portable way to manage user accounts out of the box. Payload Authentication is designed to be used in both the Admin Panel, all well as your own external applications. [More details](../authentication/overview).
## Access Control
Access Control determines what a user can and cannot do with any given Document. [More details](../access-control/overview).
Access Control determines what a user can and cannot do with any given Document, such as read, update, etc., as well as what they can and cannot see within the Admin Panel. [More details](../access-control/overview).
## Admin Panel
Payload dynamically generates a beautiful, fully type-safe interface to manage your users and data. The Admin Panel is a React application built using the Next.js App Router. [More details](../admin/overview).
## Plugins
Plugins allow for developers to easily inject custom—sometimes complex—functionality into Payload apps from a very small touch-point. [More details](../plugins/overview).
## Retrieving Data
Everything Payload does (create, read, update, delete, login, logout, etc) is exposed to you via three APIs:
Everything Payload does (create, read, update, delete, login, logout, etc.) is exposed to you via three APIs:
- [Local API](#local-api) - Extremely fast, direct-to-database access
- [REST API](#rest-api) - Standard HTTP endpoints for querying and mutating data
@@ -59,11 +59,11 @@ Everything Payload does (create, read, update, delete, login, logout, etc) is ex
### Local API
By far one of the most powerful aspects of Payload is the fact that it gives you direct-to-database access to your data through the [Local API](../local-api/overview). It's _extremely_ fast and does not incur any typical REST API / GraphQL / HTTP overhead—you query your database directly in Node.js.
By far one of the most powerful aspects of Payload is the fact that it gives you direct-to-database access to your data through the [Local API](../local-api/overview). It's _extremely_ fast and does not incur any typical HTTP overhead—you query your database directly in Node.js.
The Local API is written in TypeScript, and so it is strongly typed and extremely nice to use. It works anywhere on the server, including custom Next.js Routes, Payload Hooks, Payload Access Control, and React Server Components.
Here's a quick example of a React Server Component fetching page data with Payload's Local API:
Here's a quick example of a React Server Component fetching data using the Local API:
```tsx
import React from 'react'
@@ -100,9 +100,9 @@ const MyServerComponent: React.FC = () => {
### REST API
By default, the Payload [REST API](../rest-api/overview) will be mounted automatically for you at the `/api` path of your app.
By default, the Payload [REST API](../rest-api/overview) is mounted automatically for you at the `/api` path of your app.
For example, if you have a [Collection](../configuration/collections) called `pages`:
For example, if you have a Collection called `pages`:
```ts
fetch('https://localhost:3000/api/pages') // highlight-line
@@ -116,27 +116,17 @@ fetch('https://localhost:3000/api/pages') // highlight-line
### GraphQL API
Payload automatically exposes GraphQL queries and mutations for everything it does through a dedicated [GraphQL API](../graphql/overview).
By default, you'll find the GraphQL route handler in your `/app/(payload)/api/graphql` folder, which makes the GraphQL endpoint available by default at `http://localhost:3000/api/graphql`.
You'll also find a full GraphQL Playground which can be accessible via `http://localhost:3000/api/graphql-playground`.
Payload automatically exposes GraphQL queries and mutations through a dedicated [GraphQL API](../graphql/overview). By default, the GraphQL route handler is mounted at the `/api/graphql` path of your app. You'll also find a full GraphQL Playground which can be accessible at the `/api/graphql-playground` path of your app.
You can use any GraphQL client with Payload's GraphQL endpoint. Here are a few packages:
- [`graphql-request`](https://www.npmjs.com/package/graphql-request) - a very lightweight GraphQL client
- [`@apollo/client`](https://www.apollographql.com/docs/react/api/core/ApolloClient/) - an industry-standard GraphQL client with lots of nice features
If you don't use GraphQL, you can delete those files! But if you do, you'll find that GraphQL is a first-class API in Payload. Either way, the overhead of GraphQL is completely constrained to these endpoints, and will not slow down / affect Payload outside of those endpoints themselves.
<Banner type="info">
For more information about the GraphQL API, [click here](../graphql/overview).
</Banner>
### Depth
Documents can be related to other Documents through a concept called "relationships". When you query a Document, you can specify these relationships are populated. [More details](../queries/depth).
## Package Structure
Payload is abstracted into a set of dedicated packages to keep the core `payload` package as lightweight as possible. This allows you to only install the parts of Payload based on your unique project requirements.
@@ -172,7 +162,7 @@ All of Payload's GraphQL functionality is abstracted into a separate package. Pa
This is the UI library that Payload's Admin Panel uses. All components are exported from this package and can be re-used as you build extensions to the Payload admin UI, or want to use Payload components in your own React apps. Some exports are server components and some are client components.
`@payloadcms/db-postgres`, `@payloadcms/db-mongodb`
`@payloadcms/db-postgres`, `@payloadcms/db-vercel-postgres`, `@payloadcms/db-mongodb`
You can choose which Database Adapter you'd like to use for your project, and no matter which you choose, the entire data layer for Payload is contained within these packages. You can only use one at a time for any given project.
@@ -180,4 +170,7 @@ You can choose which Database Adapter you'd like to use for your project, and no
Payload's Rich Text functionality is abstracted into separate packages and if you want to enable Rich Text in your project, you'll need to install one of these packages. We recommend Lexical for all new projects, and this is where Payload will focus its efforts on from this point, but Slate is still supported if you have already built with it.
Rich Text is entirely optional and you may not need it for your project.
<Banner type="info">
<strong>Note:</strong>
Rich Text is entirely optional and you may not need it for your project.
</Banner>

View File

@@ -63,23 +63,13 @@ To install a Database Adapter, you can run **one** of the following commands:
```
<Banner type="success">
<strong>Reminder:</strong>
<strong>Note:</strong>
New [Database Adapters](/docs/database/overview) are becoming available every day. Check the docs for the most up-to-date list of what's available.
</Banner>
#### 2. Copy Payload files into your Next.js app folder
Payload installs directly in your Next.js `/app` folder, and you'll need to place some files into that folder for Payload to run.
The files that Payload needs to have in your `/app` folder do not regenerate, and will never change. Once you slot them in, you never have to revisit them. They are not meant to be edited and simply import Payload dependencies from `@payloadcms/next` for the REST / GraphQL API and Admin Panel UI.
You can copy the Payload `/app` folder files from the Payload blank template on GitHub:
```
https://github.com/payloadcms/payload/tree/beta/templates/blank-3.0/src/app/(payload)
```
Once you have the required Payload files in place in your `/app` folder, you should have something like this:
Payload installs directly in your Next.js `/app` folder, and you'll need to place some files into that folder for Payload to run. You can copy these files from the [Blank Template](https://github.com/payloadcms/payload/tree/beta/templates/blank/src/app/(payload)) on GitHub. Once you have the required Payload files in place in your `/app` folder, you should have something like this:
```plaintext
app/
@@ -89,10 +79,14 @@ app/
├── // Your app files
```
_For an exact reference of the `(payload)` directory, see [Project Structure](../admin/overview#project-structure)._
<Banner type="warning">
You may need to copy all of your existing frontend files, including your existing root layout, into its own newly created [Route Group](https://nextjs.org/docs/app/building-your-application/routing/route-groups), i.e. `(my-app)`.
</Banner>
The files that Payload needs to have in your `/app` folder do not regenerate, and will never change. Once you slot them in, you never have to revisit them. They are not meant to be edited and simply import Payload dependencies from `@payloadcms/next` for the REST / GraphQL API and Admin Panel.
You can name the `(my-app)` folder anything you want. The name does not matter and will just be used to clarify your directory structure for yourself. Common names might be `(frontend)`, `(app)`, or similar. [More details](../admin/overview).
#### 3. Add the Payload Plugin to your Next.js config

View File

@@ -15,7 +15,7 @@ keywords: documentation, getting started, guide, Content Management System, cms,
- A full Admin Panel using React server / client components, matching the shape of your data and completely extensible with your own React components
- Automatic database schema, including direct DB access and ownership, with migrations, transactions, proper indexing, and more
- Instant REST, GraphQL, and straight-to-DB Node APIs
- Instant REST, GraphQL, and straight-to-DB Node.js APIs
- Authentication which can be used in your own apps
- A deeply customizable access control pattern
- File storage and image management tools like cropping / focal point selection
@@ -28,14 +28,16 @@ No matter what you're building, Payload will give you backend superpowers. It ca
### Open source - deploy anywhere, including Vercel
It's fully open source with an MIT license and you can self-host anywhere that you can run a Node app. You can also deploy serverless to hosts like Vercel, right inside your existing Next.js app folder.
It's fully open source with an MIT license and you can self-host anywhere that you can run a Node.js app. You can also deploy serverless to hosts like Vercel, right inside your existing Next.js application.
### Code-first and version controlled
In Payload, there are no "click ops" - as in clicking around in an Admin Panel to define your schema. In Payload, everything is done the right way—code-first and version controlled like a proper backend. But once developers define how Payload should work, non-technical users can independently make use of its Admin Panel to manage whatever they need to without having to know code whatsoever.
### Fully extensible
Even in spite of how much you get out of the box, you still have full control over every aspect of your app - be it database, admin UI, or anything else. Every part of Payload has been designed to be extensible and customizable with modern TypeScript / React. And you'll fully understand the code that you write.
In Payload, there are no "click ops" - as in clicking around in an Admin Panel to define your schema. In Payload, everything is done the right way—code-first and version controlled like a proper backend. But once developers define how Payload should work, non-technical users can independently make use of its Admin Panel to manage whatever they need to without having to know code whatsoever.
## Use Cases
Payload started as a headless Content Management System (CMS), but since, we've seen our community leverage Payload in ways far outside of simply managing pages and blog posts. It's grown into a full-stack TypeScript app framework.

View File

@@ -21,28 +21,10 @@ export const CollectionWithHooks: CollectionConfig = {
}
```
The following Collection Hooks are available:
- [`beforeOperation`](#beforeoperation)
- [`beforeValidate`](#beforevalidate)
- [`beforeChange`](#beforechange)
- [`afterChange`](#afterchange)
- [`beforeRead`](#beforeread)
- [`afterRead`](#afterread)
- [`beforeDelete`](#beforedelete)
- [`afterDelete`](#afterdelete)
- [`afterOperation`](#afteroperation)
Additionally, all [Auth-enabled Collections](../authentication/overview) feature the following auth-related Hooks:
- [`beforeLogin`](#beforelogin)
- [`afterLogin`](#afterlogin)
- [`afterLogout`](#afterlogout)
- [`afterRefresh`](#afterrefresh)
- [`afterMe`](#afterme)
- [`afterForgotPassword`](#afterforgotpassword)
- [`refresh`](#refresh)
- [`me`](#me)
<Banner type="info">
<strong>Tip:</strong>
You can also set hooks on the field-level to isolate hook logic to specific fields. [More details](./fields).
</Banner>
## Config Options
@@ -89,9 +71,9 @@ Available Collection operations include `create`, `read`, `update`, `delete`, `l
import type { CollectionBeforeOperationHook } from 'payload'
const beforeOperationHook: CollectionBeforeOperationHook = async ({
args, // original arguments passed into the operation
operation, // name of the operation
req, // full Request object
args,
operation,
req,
}) => {
return args // return modified operation arguments as necessary
}

View File

@@ -8,7 +8,7 @@ keywords: hooks, context, payload context, payloadcontext, data, extra data, sha
The `context` object is used to share data across different Hooks. This persists throughout the entire lifecycle of a request and is available within every Hook. By setting properties to `req.context`, you can effectively logic across multiple Hooks.
## When to use Context
## When To Use Context
Context gives you a way forward on otherwise difficult problems such as:
@@ -17,11 +17,11 @@ Context gives you a way forward on otherwise difficult problems such as:
3. **Passing data to local API**: Setting values on the `req.context` and pass it to `payload.create()` you can provide additional data to hooks without adding extraneous fields.
4. **Passing data between hooks and middleware or custom endpoints**: Hooks could set context across multiple collections and then be used in a final `postMiddleware`.
## How to Use Context
## How To Use Context
Let's see examples on how context can be used in the first two scenarios mentioned above:
### Passing data between hooks
### Passing Data Between Hooks
To pass data between hooks, you can assign values to context in an earlier hook in the lifecycle of a request and expect it the context in a later hook.
@@ -58,7 +58,7 @@ const Customer: CollectionConfig = {
}
```
### Preventing infinite loops
### Preventing Infinite Loops
Let's say you have an `afterChange` hook, and you want to do a calculation inside the hook (as the document ID needed for the calculation is available in the `afterChange` hook, but not in the `beforeChange` hook). Once that's done, you want to update the document with the result of the calculation.

View File

@@ -21,14 +21,6 @@ export const FieldWithHooks: Field = {
}
```
The following Field Hooks are available:
- [`beforeValidate`](#beforevalidate)
- [`beforeChange`](#beforechange)
- [`beforeDuplicate`](#beforeduplicate)
- [`afterChange`](#afterchange)
- [`afterRead`](#afterread)
## Config Options
All Field Hooks accept an array of synchronous or asynchronous functions. These functions can optionally modify the return value of the field before the operation continues. All Field Hooks are formatted to accept the same arguments, although some arguments may be `undefined` based the specific hook type.

View File

@@ -21,13 +21,10 @@ export const GlobalWithHooks: GlobalConfig = {
}
```
The following Global Hooks are available:
- [`beforeValidate`](#beforevalidate)
- [`beforeChange`](#beforechange)
- [`afterChange`](#afterchange)
- [`beforeRead`](#beforeread)
- [`afterRead`](#afterread)
<Banner type="info">
<strong>Tip:</strong>
You can also set hooks on the field-level to isolate hook logic to specific fields. [More details](./fields).
</Banner>
## Config Options
@@ -58,11 +55,11 @@ Runs before the `update` operation. This hook allows you to add or format data b
import type { GlobalBeforeValidateHook } from 'payload'
const beforeValidateHook: GlobalBeforeValidateHook = async ({
data, // incoming data to update or create with
req, // full Request object
originalDoc, // original document
data,
req,
originalDoc,
}) => {
return data // Return data to update the document with
return data
}
```
@@ -84,11 +81,11 @@ Immediately following validation, `beforeChange` hooks will run within the `upda
import type { GlobalBeforeChangeHook } from 'payload'
const beforeChangeHook: GlobalBeforeChangeHook = async ({
data, // incoming data to update or create with
req, // full Request object
originalDoc, // original document
data,
req,
originalDoc,
}) => {
return data // Return data to update the document with
return data
}
```
@@ -110,9 +107,9 @@ After a global is updated, the `afterChange` hook runs. Use this hook to purge c
import type { GlobalAfterChangeHook } from 'payload'
const afterChangeHook: GlobalAfterChangeHook = async ({
doc, // full document data
previousDoc, // document data before updating the collection
req, // full Request object
doc,
previousDoc,
req,
}) => {
return data
}
@@ -136,8 +133,8 @@ Runs before `findOne` global operation is transformed for output by `afterRead`.
import type { GlobalBeforeReadHook } from 'payload'
const beforeReadHook: GlobalBeforeReadHook = async ({
doc, // full document data
req, // full Request object
doc,
req,
}) => {...}
```
@@ -158,9 +155,9 @@ Runs as the last step before a global is returned. Flattens locales, hides prote
import type { GlobalAfterReadHook } from 'payload'
const afterReadHook: GlobalAfterReadHook = async ({
doc, // full document data
req, // full Request object
findMany, // boolean to denote if this hook is running against finding one, or finding many (useful in versions)
doc,
req,
findMany,
}) => {...}
```

View File

@@ -2,13 +2,13 @@
title: Hooks Overview
label: Overview
order: 10
desc: Hooks allow you to add your own logic to Payload, including integrating with third-party APIs, adding auto-generated data, or modifing Payload's base functionality.
desc: Hooks allow you to add your own logic to Payload, including integrating with third-party APIs, adding auto-generated data, or modifying Payload's base functionality.
keywords: hooks, overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Hooks allow you to execute your own side effects during specific events of the Document lifecycle. With Hooks, you can transform Payload from a traditional CMS into a fully-fledged application framework. They allow you to perform business logic, third-party integrations, etc. during precise moments within the data lifecycle.
Hooks allow you to execute your own side effects during specific events of the Document lifecycle. They allow you to do things like mutate data, perform business logic, integrate with third-parties, or anything else, all during precise moments within your application.
There are many use cases for Hooks, including:
With Hooks, you can transform Payload from a traditional CMS into a fully-fledged application framework. There are many use cases for Hooks, including:
- Modify data before it is read or updated
- Encrypt and decrypt sensitive data
@@ -18,17 +18,67 @@ There are many use cases for Hooks, including:
- Send emails when contact forms are submitted
- Track data ownership or changes over time
There are three main types of Hooks in Payload:
There are four main types of Hooks in Payload:
- [Root Hooks](#root-hooks)
- [Collection Hooks](/docs/hooks/collections)
- [Global Hooks](/docs/hooks/globals)
- [Field Hooks](/docs/hooks/fields)
<Banner type="warning">
<strong>Reminder:</strong>
Payload also ships a set of _React_ hooks that you can use in your frontend application. Although they share a common name, these are very different things and should not be confused. [More details](../admin.hooks).
Payload also ships a set of _React_ hooks that you can use in your frontend application. Although they share a common name, these are very different things and should not be confused. [More details](../admin/hooks).
</Banner>
## Root Hooks
Root Hooks are not associated with any specific Collection, Global, or Field. They are useful for globally-oriented side effects, such as when an error occurs at the application level.
To add Root Hooks, use the `hooks` property in your [Payload Config](/docs/configuration/config):
```ts
import { buildConfig } from 'payload'
export default buildConfig({
// ...
// highlight-start
hooks: {
afterError: () => {...}
},
// highlight-end
})
```
The following options are available:
| Option | Description |
|--------------|-----------------------------------------------------------------------------------------------|
| **`afterError`** | Runs after an error occurs in the Payload application. |
### afterError
The `afterError` Hook is triggered when an error occurs in the Payload application. This can be useful for logging errors to a third-party service, sending an email to the development team, logging the error to Sentry or DataDog, etc.
```ts
import { buildConfig } from 'payload'
export default buildConfig({
// ...
hooks: {
afterError: async ({ error }) => {
// Do something
}
},
})
```
The following arguments are provided to the `afterError` Hook:
| Argument | Description |
|----------|-----------------------------------------------------------------------------------------------|
| **`error`** | The error that occurred. |
| **`context`** | Custom context passed between Hooks. [More details](./context). |
## Async vs. Synchronous
All Hooks can be written as either synchronous or asynchronous functions. Choosing the right type depends on your use case, but switching between the two is as simple as adding or removing the `async` keyword.

View File

@@ -18,9 +18,10 @@ IMPORTANT: This will overwrite all slate data. We recommend doing the following
1. Take a backup of your entire database. If anything goes wrong and you do not have a backup, you are on your own and will not receive any support.
2. Make every richText field a lexical editor. This script will only convert lexical richText fields with old Slate data
3. Add the SlateToLexicalFeature (as seen below) first, and test it out by loading up the Admin Panel, to see if the migrator works as expected. You might have to build some custom converters for some fields first in order to convert custom Slate nodes. The SlateToLexicalFeature is where the converters are stored. Only fields with this feature added will be migrated.
4. If this works as expected, add the `disableHooks: true` prop everywhere you're initializing `SlateToLexicalFeature`. Example: `SlateToLexicalFeature({ disableHooks: true })`. Once you did that, you're ready to run the migration script.
```ts
import { migrateSlateToLexical } from '@payloadcms/richtext-lexical'
import { migrateSlateToLexical } from '@payloadcms/richtext-lexical/migrate'
await migrateSlateToLexical({ payload })
```
@@ -34,7 +35,8 @@ Simply add the `SlateToLexicalFeature` to your editor:
```ts
import type { CollectionConfig } from 'payload'
import { SlateToLexicalFeature, lexicalEditor } from '@payloadcms/richtext-lexical'
import { SlateToLexicalFeature } from '@payloadcms/richtext-lexical/migrate'
import { lexicalEditor } from '@payloadcms/richtext-lexical'
const Pages: CollectionConfig = {
slug: 'pages',
@@ -64,8 +66,8 @@ The easy way to solve this: Edit the richText field and save the document! This
If you have custom Slate nodes, create a custom converter for them. Here's the Upload converter as an example:
```ts
import type { SerializedUploadNode } from '../uploadNode.'
import type { SlateNodeConverter } from '@payloadcms/richtext-lexical'
import type { SerializedUploadNode } from '../uploadNode'
import type { SlateNodeConverter } from '@payloadcms/richtext-lexical/migrate'
export const SlateUploadConverter: SlateNodeConverter = {
converter({ slateNode }) {
@@ -95,9 +97,9 @@ When using the `SlateToLexicalFeature`, you can add your custom converters to th
```ts
import type { CollectionConfig } from 'payload'
import { lexicalEditor } from '@payloadcms/richtext-lexical'
import {
SlateToLexicalFeature,
lexicalEditor,
defaultSlateConverters,
} from '@payloadcms/richtext-lexical'

View File

@@ -8,7 +8,7 @@ keywords: live preview, preview, live, iframe, iframe preview, visual editing, d
With Live Preview you can render your front-end application directly within the [Admin Panel](../admin/overview). As you type, your changes take effect in real-time. No need to save a draft or publish your changes. This works in both [Server-side](./server) as well as [Client-side](./client) environments.
Live Preview works by rendering an iframe on the page that loads your front-end application. The Admin Panel communicates with your app through [`window.postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) events. These events are emitted every time a change is made to the document. Your app then listens for these events and re-renders itself with the data it receives.
Live Preview works by rendering an iframe on the page that loads your front-end application. The Admin Panel communicates with your app through [`window.postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) events. These events are emitted every time a change is made to the Document. Your app then listens for these events and re-renders itself with the data it receives.
To add Live Preview, use the `admin.livePreview` property in your [Payload Config](../configuration/overview):
@@ -28,12 +28,16 @@ const config = buildConfig({
}
})
```
<Banner type="warning">
<strong>Reminder:</strong>
Alternatively, you can define the <code>admin.livePreview</code> property on individual [Collection Admin Configs](../admin/collections) and [Global Admin Configs](../admin/globals). Settings defined here will be merged into the top-level as overrides.
</Banner>
{/* IMAGE OF LIVE PREVIEW HERE */}
## Options
Setting up Live Preview is easy. This can be done either globally through the [Root Config](../configuration/overview), or on individual [Collection](../configuration/collections) and [Global](../configuration/globals) configs. Once configured, a new "Live Preview" tab will appear at the top of enabled documents. Navigating to this tab opens the preview window and loads your front-end application.
Setting up Live Preview is easy. This can be done either globally through the [Root Admin Config](../admin/overview), or on individual [Collection Admin Configs](../admin/collections) and [Global Admin Configs](../admin/globals). Once configured, a new "Live Preview" tab will appear at the top of enabled Documents. Navigating to this tab opens the preview window and loads your front-end application.
The following options are available:
@@ -46,11 +50,6 @@ The following options are available:
_\* An asterisk denotes that a property is required._
<Banner type="warning">
<strong>Reminder:</strong>
Alternatively, you can define the <code>admin.livePreview</code> property on individual [Collection](../configuration/collections) and [Global](../configuration/globals) configs. Settings defined here will be merged into the top-level as overrides.
</Banner>
### URL
The `url` property is a string that points to your front-end application. This value is used as the `src` attribute of the iframe rendering your front-end. Once loaded, the Admin Panel will communicate directly with your app through `window.postMessage` events.
@@ -74,7 +73,7 @@ const config = buildConfig({
#### Dynamic URLs
You can also pass a function in order to dynamically format URLs. This is useful for multi-tenant applications, localization, or any other scenario where the URL needs to be generated based on the document being edited.
You can also pass a function in order to dynamically format URLs. This is useful for multi-tenant applications, localization, or any other scenario where the URL needs to be generated based on the Document being edited.
To set dynamic URLs, set the `admin.livePreview.url` property in your [Payload Config](../configuration/overview) to a function:
@@ -105,8 +104,8 @@ The following arguments are provided to the `url` function:
| Path | Description |
| ------------------ | ----------------------------------------------------------------------------------------------------------------- |
| **`data`** | The data of the document being edited. This includes changes that have not yet been saved. |
| **`documentInfo`** | Information about the document being edited like collection slug. [More details](../admin/hooks#usedocumentinfo). |
| **`data`** | The data of the Document being edited. This includes changes that have not yet been saved. |
| **`documentInfo`** | Information about the Document being edited like collection slug. [More details](../admin/hooks#usedocumentinfo). |
| **`locale`** | The locale currently being edited (if applicable). [More details](../configuration/localization). |
### Breakpoints

View File

@@ -2,11 +2,11 @@
title: Using Payload outside Next.js
label: Outside Next.js
order: 20
desc: Payload can be used outside of Next.js within standalone scripts or in other frameworks like Remix, Sveltekit, Nuxt, and similar.
desc: Payload can be used outside of Next.js within standalone scripts or in other frameworks like Remix, SvelteKit, Nuxt, and similar.
keywords: local api, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
---
Payload can be used completely outside of Next.js which is helpful in cases like running scripts, using Payload in a separate backend service, or using Payload's Local API to fetch your data directly from your database in other frontend frameworks like Sveltekit, Remix, Nuxt, and similar.
Payload can be used completely outside of Next.js which is helpful in cases like running scripts, using Payload in a separate backend service, or using Payload's Local API to fetch your data directly from your database in other frontend frameworks like SvelteKit, Remix, Nuxt, and similar.
<Banner>
<strong>Note:</strong>
@@ -16,38 +16,16 @@ Payload can be used completely outside of Next.js which is helpful in cases like
## Importing the Payload Config outside of Next.js
Your Payload Config likely has imports which need to be handled properly, such as CSS imports and similar. If you were to try and import your config without any Node support for SCSS / CSS files, you'll see errors that arise accordingly.
Payload provides a convenient way to run standalone scripts, which can be useful for tasks like seeding your database or performing one-off operations.
This is especially relevant if you are importing your Payload Config outside of a bundler context, such as in standalone Node scripts.
For these cases, you can use Payload's `importConfig` function to handle importing your config safely. It will handle everything you need to be able to load and use your Payload Config, without any client-side files present.
Here's an example of a seed script that creates a few documents for local development / testing purposes, using Payload's `importConfig` function to safely import Payload, and the `getPayload` function to retrieve an initialized copy of Payload.
In standalone scripts, can simply import the Payload Config and use it right away. If you need an initialized copy of Payload, you can then use the `getPayload` function. This can be useful for tasks like seeding your database or performing other one-off operations.
```ts
// We are importing `getPayload` because we don't need HMR
// for a standalone script. For usage of Payload inside Next.js,
// you should always use `import { getPayloadHMR } from '@payloadcms/next/utilities'` instead.
import { getPayload } from 'payload'
// This is a helper function that will make sure we can safely load the Payload Config
// and all of its client-side files, such as CSS, SCSS, etc.
import { importConfig } from 'payload/node'
import path from 'path'
import { fileURLToPath } from 'node:url'
import dotenv from 'dotenv'
// In ESM, you can create the "dirname" variable
// like this. We'll use this with `dotenv` to load our `.env` file, if necessary.
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
// If you don't need to load your .env file,
// then you can skip this part!
dotenv.config({
path: path.resolve(dirname, '../.env'),
})
import config from '@payload-config'
const seed = async () => {
// Get a local copy of Payload by passing your config
@@ -71,6 +49,39 @@ const seed = async () => {
}
// Call the function here to run your seed script
seed()
await seed()
```
You can then execute the script using `payload run`. Example: if you placed this standalone script in `src/seed.ts`, you would execute it like this:
```sh
payload run src/seed.ts
```
The `payload run` command does two things for you:
1. It loads the environment variables the same way Next.js loads them, eliminating the need for additional dependencies like `dotenv`. The usage of `dotenv` is not recommended, as Next.js loads environment variables differently. By using `payload run`, you ensure consistent environment variable handling across your Payload and Next.js setup.
2. It initializes tsx, allowing direct execution of TypeScript files manually installing tools like tsx or ts-node.
### Troubleshooting
If you encounter import-related errors, you have 2 options:
#### Option 1: enable swc mode by appending `--use-swc` to the `payload` command:
Example:
```sh
payload run src/seed.ts --use-swc
```
Note: Install @swc-node/register in your project first. While swc mode is faster than the default tsx mode, it might break for some imports.
#### Option 2: use an alternative runtime like bun
While we do not guarantee support for alternative runtimes, you are free to use them and disable payloads own transpilation by appending the `--disable-transpilation` flag to the `payload` command:
```sh
bunx --bun payload run src/seed.ts --disable-transpile
```
You will need to have bun installed on your system for this to work.

View File

@@ -62,19 +62,16 @@ If you are accessing Payload via function arguments or `req.payload`, HMR is aut
**Option 2 - outside of Next.js**
If you are using Payload outside of Next.js, for example in standalone scripts or in other frameworks, you can import Payload with no HMR functionality.
If you are using Payload outside of Next.js, for example in standalone scripts or in other frameworks, you can import Payload with no HMR functionality. Instead of using `getPayloadHMR`, you can use `getPayload`.
```ts
import { getPayload } from 'payload'
import { importConfig } from 'payload/node'
import config from '@payload-config'
const config = await importConfig('./payload.config.ts')
const payload = await getPayload({ config })
```
Both options function in exactly the same way outside of one having HMR support and the other not. However, when you import your Payload Config, you need to make sure that you can import it safely.
For more information about using Payload outside of Next.js, [click here](/docs/beta/local-api/outside-nextjs).
Both options function in exactly the same way outside of one having HMR support and the other not. For more information about using Payload outside of Next.js, [click here](/docs/beta/local-api/outside-nextjs).
## Local options available

View File

@@ -159,7 +159,6 @@ import {
useAllFormFields,
useAuth,
useClientFunctions,
useComponentMap,
useConfig,
useDebounce,
useDebouncedCallback,
@@ -180,7 +179,6 @@ import {
useFormInitializing,
useFormModified,
useFormProcessing,
useFormQueryParams,
useFormSubmitted,
useHotkey,
useIntersect,
@@ -213,7 +211,6 @@ import {
ActionsProvider,
AuthProvider,
ClientFunctionProvider,
ComponentMapProvider,
ConfigProvider,
DocumentEventsProvider,
DocumentInfoProvider,
@@ -221,7 +218,6 @@ import {
EntityVisibilityProvider,
FieldComponentsProvider,
FieldPropsProvider,
FormQueryParamsProvider,
ListInfoProvider,
ListQueryProvider,
LocaleProvider,
@@ -301,14 +297,10 @@ import {
fieldBaseClass,
// TS Types
ActionMap,
CollectionComponentMap,
ColumnPreferences,
ConfigComponentMapBase,
DocumentInfoContext,
DocumentInfoProps,
FieldType,
FieldComponentProps,
FormProps,
RowLabelProps,
SelectFieldProps,
@@ -325,7 +317,6 @@ import {
AppHeader,
BlocksDrawer,
Column,
ComponentMap,
DefaultBlockImage,
DeleteMany,
DocumentControls,
@@ -337,11 +328,9 @@ import {
FieldMap,
File,
Form,
FormFieldBase,
FormLoadingOverlayToggle,
FormSubmit,
GenerateConfirmation,
GlobalComponentMap,
HydrateClientUser,
ListControls,
ListSelection,
@@ -352,7 +341,8 @@ import {
PublishMany,
ReactSelect,
ReactSelectOption,
ReducedBlock,
ClientField,
ClientBlock,
RenderFields,
SectionTitle,
Select,
@@ -477,10 +467,10 @@ export const ServerRenderedDescription = () => <ClientRenderedDescription />
// file: components/ClientRenderedDescription.tsx
'use client'
import React from 'react'
import type { DescriptionComponent } from 'payload'
import type { TextFieldDescriptionClientComponent } from 'payload'
import { useFieldProps, useFormFields } from '@payloadcms/ui'
export const ClientRenderedDescription: DescriptionComponent = () ={
export const ClientRenderedDescription: TextFieldDescriptionClientComponent = () ={
const { path } = useFieldProps()
const { value } = useFormFields(([fields]) => fields[path])
const customDescription = `Component description: ${path} - ${value}`
@@ -669,8 +659,8 @@ export const ClientArrayRowLabel = () => {
admin: {
components: {
views: {
Edit: {
Tab: {
edit: {
tab: {
pillLabel: '',
},
},
@@ -685,9 +675,11 @@ export const ClientArrayRowLabel = () => {
admin: {
components: {
views: {
Edit: {
Tab: {
Pill: MyPill,
edit: {
tab: {
pill: {
Component: './path/to/CustomPill.js',
},
},
},
},
@@ -719,7 +711,7 @@ import type { FormState } from 'payload'
This is because the configs themselves are not serializable and so they cannot be thread through to the client, i.e. the `DocumentInfoContext`. Instead, various properties of the config are passed instead, like `collectionSlug` and `globalSlug`. You can use these to access a client-side config, if needed, through the `useConfig` hook (see next bullet).
17. The `useConfig` hook now returns a `ClientConfig` and not a `SanizitedConfig`.
17. The `useConfig` hook now returns a `ClientConfig` and not a `SanitizedConfig`.
This is because the config itself is not serializable and so it is not able to be thread through to the client, i.e. the `ConfigContext`.

View File

@@ -1,7 +1,7 @@
---
title: Building Your Own Plugin
label: Build Your Own
order: 50
order: 20
desc: Starting to build your own plugin? Find everything you need and learn best practices with the Payload plugin template.
keywords: plugins, template, config, configuration, extensions, custom, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
@@ -159,36 +159,60 @@ export const seed = async (payload: Payload): Promise<void> => {
```
## Overview of the src folder
## Building a Plugin
Now that we have our environment setup and dev project ready to go - it&apos;s time to build the plugin!
**index.ts**
First up, the `src/index.ts` file - this is where the plugin should be imported from. It is best practice not to build the plugin directly in this file, instead we use this to export the plugin and types from their respective files.
**Plugin.ts**
To reiterate, the essence of a [Payload Plugin](./overview) is simply to extend the [Payload Config](../configuration/overview) - and that is exactly what we are doing in this file.
```
import type { Config } from 'payload'
export const samplePlugin =
(pluginOptions: PluginTypes) =>
(incomingConfig: Config): Config => {
// create copy of incoming config
let config = { ...incomingConfig }
// do something cool with the config here
/**
* This is where you could modify the
* config based on the plugin options
*/
// If you wanted to add a new collection:
config.collections = [
...(config.collections || []),
newCollection,
]
// If you wanted to add a new global:
config.globals = [
...(config.globals || []),
newGlobal,
]
/**
* If you wanted to add a new field to a collection:
*
* 1. Loop over collections
* 2. Find the collection you want to add the field to
* 3. Add the field to the collection
*/
// If you wanted to add to the onInit:
config.onInit = async payload => {
if (incomingConfig.onInit) await incomingConfig.onInit(payload)
// Add additional onInit code here
}
// Finally, return the modified config
return config
}
```
1. First, you need to receive the existing Payload Config along with any plugin options.
2. Then set the variable `config` to be equal to a copy of the existing config.
3. From here, you can extend the config however you like!
4. Finally, return the config and you&apos;re all set.
To reiterate, the essence of a [Payload Plugin](./overview) is simply to extend the [Payload Config](../configuration/overview) - and that is exactly what we are doing in this file.
## Spread Syntax
### Spread syntax
[Spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) (or the spread operator) is a feature in JavaScript that uses the dot notation **(...)** to spread elements from arrays, strings, or objects into various contexts.
@@ -206,7 +230,7 @@ config.collections = [
First, you need to spread the `config.collections` to ensure that we don&apos;t lose the existing collections. Then you can add any additional collections, just as you would in a regular Payload Config.
This same logic is applied to other properties like admin, globals, hooks:
This same logic is applied to other array and object like properties such as admin, globals and hooks:
```
config.globals = [
@@ -220,7 +244,10 @@ config.hooks = {
}
```
Some properties will be slightly different to extend, for instance the `onInit` property:
### Extending functions
Function properties cannot use spread syntax. The way to extend them is to execute the existing function if it exists and then run your additional functionality.
Here is an example extending the `onInit` property:
```
config.onInit = async payload => {
@@ -231,10 +258,6 @@ config.onInit = async payload => {
}
```
If you wish to add to the `onInit`, you must include the async/await. We don&apos;t use spread syntax in this case, instead you must await the existing `onInit` before running additional functionality.
In the template, we have stubbed out a basic `onInitExtension` file that you can use, if not needed feel free to delete it.
## Types
If your plugin has options, you should define and provide types for these options in a separate file which gets exported from the main `index.ts`.

View File

@@ -1,7 +1,7 @@
---
title: Form Builder Plugin
label: Form Builder
order: 20
order: 40
desc: Easily build and manage forms from the Admin Panel. Send dynamic, personalized emails and even accept and process payments.
keywords: plugins, plugin, form, forms, form builder
---
@@ -109,7 +109,7 @@ The `beforeEmail` property is a [beforeChange](<[beforeChange](https://payloadcm
// payload.config.ts
formBuilder({
// ...
beforeEmail: (emailsToSend) => {
beforeEmail: (emailsToSend, beforeChangeParams) => {
// modify the emails in any way before they are sent
return emails.map((email) => ({
...email,
@@ -119,6 +119,23 @@ formBuilder({
})
```
For full types with `beforeChangeParams`, you can import the types from the plugin:
```ts
import type { BeforeEmail } from '@payloadcms/plugin-form-builder'
// Your generated FormSubmission type
import type {FormSubmission} from '@payload-types'
// Pass it through and 'data' or 'originalDoc' will now be typed
const beforeEmail: BeforeEmail<FormSubmission> = (emailsToSend, beforeChangeParams) => {
// modify the emails in any way before they are sent
return emails.map((email) => ({
...email,
html: email.html, // transform the html in any way you'd like (maybe wrap it in an html template?)
}))
}
```
### `formOverrides`
Override anything on the `forms` collection by sending a [Payload Collection Config](https://payloadcms.com/docs/configuration/collections) to the `formOverrides` property.

View File

@@ -1,7 +1,7 @@
---
title: Nested Docs Plugin
label: Nested Docs
order: 20
order: 40
desc: Nested documents in a parent, child, and sibling relationship.
keywords: plugins, nested, documents, parent, child, sibling, relationship
---

View File

@@ -6,7 +6,7 @@ desc: Plugins provide a great way to modularize Payload functionalities into eas
keywords: plugins, config, configuration, extensions, custom, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Payload Plugins take full advantage of the modularity of the [Payload Config](../configuration/overview), allowing developers to extend Payload's core functionality in a precise and granular way. This pattern allows developers to easily inject custom—sometimes complex—functionality into Payload apps from a very small touch-point.
Payload Plugins take full advantage of the modularity of the [Payload Config](../configuration/overview), allowing developers developers to easily inject custom—sometimes complex—functionality into Payload apps from a very small touch-point. This is especially useful is sharing your work across multiple projects or with the greater Payload community.
There are many [Official Plugins](#official-plugins) available that solve for some of the most common uses cases, such as the [Form Builder Plugin](./seo) or [SEO Plugin](./seo). There are also [Community Plugins](#community-plugins) available, maintained entirely by contributing members. To extend Payload's functionality in some other way, you can easily [build your own plugin](./build-your-own).

View File

@@ -1,7 +1,7 @@
---
title: Redirects Plugin
label: Redirects
order: 20
order: 40
desc: Automatically create redirects for your Payload application
keywords: plugins, redirects, redirect, plugin, payload, cms, seo, indexing, search, search engine
---
@@ -66,6 +66,8 @@ export default config
| ------------- | ---------- | ----------------------------------------------------------------------------------------------- |
| `collections` | `string[]` | An array of collection slugs to populate in the `to` field of each redirect. |
| `overrides` | `object` | A partial collection config that allows you to override anything on the `redirects` collection. |
| `redirectTypes` | `string[]` | Provide an array of redirects if you want to provide options for the type of redirects to be supported. |
| `redirectTypeFieldOverride` | `Field` | A partial Field config that allows you to override the Redirect Type field if enabled above. |
Note that the fields in overrides take a function that receives the default fields and returns an array of fields. This allows you to add fields to the collection.
@@ -83,6 +85,10 @@ redirectsPlugin({
]
},
},
redirectTypes: ['301', '302'],
redirectTypeFieldOverride: {
label: 'Redirect Type (Overridden)',
},
})
```

View File

@@ -1,7 +1,7 @@
---
title: Search Plugin
label: Search
order: 20
order: 40
desc: Generates records of your documents that are extremely fast to search on.
keywords: plugins, search, search plugin, search engine, search index, search results, search bar, search box, search field, search form, search input
---

View File

@@ -1,7 +1,7 @@
---
title: Sentry Plugin
label: Sentry
order: 20
order: 40
desc: Integrate Sentry error tracking into your Payload application
keywords: plugins, sentry, error, tracking, monitoring, logging, bug, reporting, performance
---

View File

@@ -1,7 +1,7 @@
---
title: SEO Plugin
label: SEO
order: 20
order: 30
desc: Manage SEO metadata from your Payload admin
keywords: plugins, seo, meta, search, engine, ranking, google
---
@@ -119,7 +119,7 @@ A function that allows you to return any meta title, including from document's c
{
// ...
seoPlugin({
generateTitle: ({ ...docInfo, doc, locale }) => `Website.com — ${doc?.title}`,
generateTitle: ({ ...docInfo, doc, locale, req }) => `Website.com — ${doc?.title}`,
})
}
```
@@ -133,7 +133,7 @@ A function that allows you to return any meta description, including from docume
{
// ...
seoPlugin({
generateDescription: ({ ...docInfo, doc, locale }) => doc?.excerpt,
generateDescription: ({ ...docInfo, doc, locale, req }) => doc?.excerpt,
})
}
```
@@ -147,7 +147,7 @@ A function that allows you to return any meta image, including from document's c
{
// ...
seoPlugin({
generateImage: ({ ...docInfo, doc, locale }) => doc?.featuredImage,
generateImage: ({ ...docInfo, doc, locale, req }) => doc?.featuredImage,
})
}
```
@@ -161,7 +161,7 @@ A function called by the search preview component to display the actual URL of y
{
// ...
seoPlugin({
generateURL: ({ ...docInfo, doc, locale }) =>
generateURL: ({ ...docInfo, doc, locale, req }) =>
`https://yoursite.com/${collection?.slug}/${doc?.slug}`,
})
}

View File

@@ -1,7 +1,7 @@
---
title: Stripe Plugin
label: Stripe
order: 20
order: 40
desc: Easily accept payments with Stripe
keywords: plugins, stripe, payments, ecommerce
---

View File

@@ -47,7 +47,7 @@ deploying to Production, it's a good idea to double-check that you are making pr
### The Secret Key
When you initialize Payload, you provide it with a `secret` property. This property should be impossible to guess and
extremely difficult for brute-force attacks to crack. Make sure your Production `secret` is a long, complex string.
extremely difficult for brute-force attacks to crack. Make sure your Production `secret` is a long, complex string.
### Double-check and thoroughly test all Access Control
@@ -78,7 +78,7 @@ Note that this is different than running `next dev`. Generally, Next.js apps com
### Secure Cookie Settings
You should be using an SSL certificate for production Payload instances, which means you
can [enable secure cookies](/docs/authentication/config) in your Authentication-enabled Collection configs.
can [enable secure cookies](/docs/authentication/overview) in your Authentication-enabled Collection configs.
### Preventing API Abuse
@@ -88,7 +88,7 @@ more. [Click here to learn more](/docs/production/preventing-abuse).
## Database
Payload can be used with any Postgres database or MongoDB-compatible database including AWS DocumentDB or Azure Cosmos DB. Make sure your production environment has access to the database that Payload uses.
Payload can be used with any Postgres database or MongoDB-compatible database including AWS DocumentDB or Azure Cosmos DB. Make sure your production environment has access to the database that Payload uses.
Out of the box, Payload templates pass the `process.env.DATABASE_URI` environment variable to its database adapters, so make sure you've got that environment variable (and all others that you use) assigned in your deployment platform.

View File

@@ -38,7 +38,7 @@ If you do not need GraphQL it is advised that you disable it altogether with the
Payload does not execute uploaded files on the server, but depending on your setup it may be used to transmit and store potentially dangerous files. If your configuration allows file uploads there is the potential that a bad actor uploads a malicious file that is then served to other users. Consider the following ways to mitigate the risks.
First, enable email [verification](/docs/authentication/config#email-verification) when users are allowed to register new accounts and add other bot prevention services.
First, enable email [verification](/docs/authentication/overview#email-verification) when users are allowed to register new accounts and add other bot prevention services.
Review that `create` and `update` access on file upload collections are as restrictive as your application needs allow. Consider limiting `read` access of uploaded user's files and how you might limit user uploaded files from being served outside of Payload.

View File

@@ -6,7 +6,7 @@ desc: Payload provides a querying language through all APIs, allowing you to fil
keywords: query, documents, overview, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
In Payload, "querying" means filtering or searching through Documents within a [Collection](../configuration/collections). The querying language in Payload is designed to be simple and powerful, allowing you to filter documents with extreme precision.
In Payload, "querying" means filtering or searching through Documents within a [Collection](../configuration/collections). The querying language in Payload is designed to be simple and powerful, allowing you to filter Documents with extreme precision through an intuitive and standardized structure.
Payload provides three common APIs for querying your data:

View File

@@ -599,7 +599,7 @@ export const Orders: CollectionConfig = {
{
path: '/:id/tracking',
method: 'get',
handler: (req) => {
handler: async (req) => {
const tracking = await getTrackingInfo(req.params.id)
if (!tracking) {
@@ -614,7 +614,7 @@ export const Orders: CollectionConfig = {
{
path: '/:id/tracking',
method: 'post',
handler: (req) => {
handler: async (req) => {
// `data` is not automatically appended to the request
// if you would like to read the body of the request
// you can use `data = await req.json()`
@@ -654,7 +654,7 @@ import { addDataAndFileToRequest } from '@payloadcms/next/utilities'
{
path: '/:id/tracking',
method: 'post',
handler: (req) => {
handler: async (req) => {
await addDataAndFileToRequest(req)
await req.payload.update({
collection: 'tracking',
@@ -680,7 +680,7 @@ import { addLocalesToRequestFromData } from '@payloadcms/next/utilities'
{
path: '/:id/tracking',
method: 'post',
handler: (req) => {
handler: async (req) => {
await addLocalesToRequestFromData(req)
// you now can access req.locale & req.fallbackLocale
return Response.json({ message: 'success' })

View File

@@ -106,7 +106,7 @@ For example, let's look at the following simple Payload Config:
import type { Config } from 'payload'
const config: Config = {
serverURL: process.env.PAYLOAD_PUBLIC_SERVER_URL,
serverURL: process.env.NEXT_PUBLIC_SERVER_URL,
admin: {
user: 'users',
},

View File

@@ -92,10 +92,13 @@ _An asterisk denotes that an option is required._
| Option | Description |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`adminThumbnail`** | Set the way that the [Admin Panel](../admin/overview) will display thumbnails for this Collection. [More](#admin-thumbnails) |
| **`bulkUpload`** | Allow users to upload in bulk from the list view, default is true |
| **`crop`** | Set to `false` to disable the cropping tool in the [Admin Panel](../admin/overview). Crop is enabled by default. [More](#crop-and-focal-point-selector) |
| **`disableLocalStorage`** | Completely disable uploading files to disk locally. [More](#disabling-local-upload-storage) |
| **`displayPreview`** | Enable displaying preview of the uploaded file in Upload fields related to this Collection. Can be locally overridden by `displayPreview` option in Upload field. [More](/docs/fields/upload#config-options). |
| **`externalFileHeaderFilter`** | Accepts existing headers and returns the headers after filtering or modifying. |
| **`filesRequiredOnCreate`** | Mandate file data on creation, default is true. |
| **`filenameCompoundIndex`** | Field slugs to use for a compount index instead of the default filename index.
| **`focalPoint`** | Set to `false` to disable the focal point selection tool in the [Admin Panel](../admin/overview). The focal point selector is only available when `imageSizes` or `resizeOptions` are defined. [More](#crop-and-focal-point-selector) |
| **`formatOptions`** | An object with `format` and `options` that are used with the Sharp image library to format the upload file. [More](https://sharp.pixelplumbing.com/api-output#toformat) |
| **`handlers`** | Array of Request handlers to execute when fetching a file, if a handler returns a Response it will be sent to the client. Otherwise Payload will retrieve and send back the file. |
@@ -104,6 +107,7 @@ _An asterisk denotes that an option is required._
| **`resizeOptions`** | An object passed to the the Sharp image library to resize the uploaded file. [More](https://sharp.pixelplumbing.com/api-resize) |
| **`staticDir`** | The folder directory to use to store media in. Can be either an absolute path or relative to the directory that contains your config. Defaults to your collection slug |
| **`trimOptions`** | An object passed to the the Sharp image library to trim the uploaded file. [More](https://sharp.pixelplumbing.com/api-resize#trim) |
| **`withMetadata`** | If specified, appends metadata to the output image file. Accepts a boolean or a function that receives `metadata` and `req`, returning a boolean. |
### Payload-wide Upload Options
@@ -167,6 +171,22 @@ When an uploaded image is smaller than the defined image size, we have 3 options
image size. Use the `withoutEnlargement` prop to change this.
</Banner>
#### Custom file name per size
Each image size supports a `generateImageName` function that can be used to generate a custom file name for the resized image.
This function receives the original file name, the resize name, the extension, height and width as arguments.
```ts
{
name: 'thumbnail',
width: 400,
height: 300,
generateImageName: ({ height, sizeName, extension, width }) => {
return `custom-${sizeName}-${height}-${width}.${extension}`
},
}
```
## Crop and Focal Point Selector
This feature is only available for image file types.

Some files were not shown because too many files have changed in this diff Show More