General
Code Style
- Use
camelCasefor all field names. - Always include
admin.descriptionfor Payload collections and fields. - Collection slugs should be lowercase with hyphens (e.g.
'media','form-submissions'). - Leverage helper functions from
payload-helperpackage for common patterns.
Collection Configuration
Collections follow Payload’s CollectionConfig type with specific conventions:
1export const Listings: CollectionConfig = {
2 slug: 'listings',
3 timestamps: true,
4 trash: true,
5 versions: {
6 drafts: true,
7 maxPerDoc: 10,
8 },
9 admin: {
10 useAsTitle: 'title',
11 defaultColumns: ['id', 'title', 'vehicle', 'manufacturer'],
12 preview: (doc): string | null => {
13 return `${frontendURL()}${doc.url}`
14 },
15 },
16 access: {
17 read: adminsAndCreatedBy,
18 create: ({ req }) => !!req.user,
19 update: adminsAndCreatedBy,
20 delete: admins,
21 admin: admins,
22 },
23 fields: [
24 {
25 name: 'title',
26 type: 'text',
27 required: true,
28 maxLength: 80,
29 admin: {
30 description: `What part are you selling? Keep it clear and under 80 characters.`,
31 },
32 },
33 // ... more fields
34 ],
35}
Access Control
- Create separate access control functions for reusability.
- Use role-based access control (RBAC).
- Define condition functions for field-level visibility.
Example:
1import { checkRole } from './checkRole'
2
3export const admins = (args: { req: { user?: any } }): boolean => {
4 const user = args?.req?.user
5 return checkRole(Roles.Admin, user) || checkRole(Roles.SuperAdmin, user)
6}
7
8export const adminOnly = {
9 read: admins,
10 create: admins,
11 update: admins,
12 delete: admins,
13 unlock: admins,
14}
Preview URLs
Always configure preview URLs for collections that have corresponding frontend pages:
1admin: {
2 preview: (doc): string | null => {
3 return `${frontendURL()}${doc.url}`
4 },
5}