0
# Configuration System
1
2
Comprehensive configuration system for defining collections, globals, fields, authentication, and admin settings. The configuration serves as the foundation for your entire Payload CMS setup.
3
4
## Capabilities
5
6
### Configuration Builder
7
8
Core function for building and validating Payload configuration with plugin support.
9
10
```typescript { .api }
11
/**
12
* Builds and validates Payload configuration with plugin processing
13
* @param config - The Payload configuration object
14
* @returns Sanitized and validated configuration
15
*/
16
function buildConfig(config: Config): SanitizedConfig;
17
18
/**
19
* Plugin function type for extending Payload functionality
20
*/
21
type Plugin = (config: Config) => Config;
22
```
23
24
**Usage Examples:**
25
26
```typescript
27
import { buildConfig } from "payload/config";
28
29
const config = buildConfig({
30
collections: [
31
// your collections
32
],
33
globals: [
34
// your globals
35
],
36
plugins: [
37
// plugin functions that modify config
38
myCustomPlugin(),
39
anotherPlugin(options),
40
],
41
// ... other config options
42
});
43
44
// Plugin example
45
function myCustomPlugin(): Plugin {
46
return (config: Config) => {
47
// Modify and return config
48
return {
49
...config,
50
// Add custom collections, modify existing config, etc.
51
};
52
};
53
}
54
```
55
56
### Main Configuration
57
58
The primary configuration object that defines your entire Payload setup.
59
60
```typescript { .api }
61
/**
62
* Main Payload configuration interface
63
*/
64
interface Config {
65
/** Base URL for your server (required for emails and admin) */
66
serverURL?: string;
67
/** Array of collection configurations */
68
collections?: CollectionConfig[];
69
/** Array of global configurations */
70
globals?: GlobalConfig[];
71
/** Admin panel configuration */
72
admin?: AdminConfig;
73
/** Authentication configuration */
74
auth?: AuthConfig;
75
/** Email service configuration */
76
email?: EmailConfig;
77
/** File upload configuration */
78
upload?: UploadConfig;
79
/** Internationalization configuration */
80
localization?: LocalizationConfig;
81
/** TypeScript configuration */
82
typescript?: TypeScriptConfig;
83
/** GraphQL configuration */
84
graphQL?: GraphQLConfig;
85
/** CORS configuration */
86
cors?: CORSConfig;
87
/** CSRF protection configuration */
88
csrf?: CSRFConfig;
89
/** Express configuration */
90
express?: ExpressConfig;
91
/** API route configuration */
92
routes?: {
93
/** Admin panel route (default: "/admin") */
94
admin?: string;
95
/** API base route (default: "/api") */
96
api?: string;
97
/** GraphQL endpoint (default: "/api/graphql") */
98
graphQL?: string;
99
/** GraphQL playground route (default: "/api/graphql-playground") */
100
graphQLPlayground?: string;
101
};
102
/** Rate limiting configuration */
103
rateLimit?: RateLimitConfig;
104
/** Global hooks */
105
hooks?: {
106
/** Hook called after errors occur */
107
afterError?: AfterErrorHook;
108
};
109
/** Enable/disable telemetry */
110
telemetry?: boolean;
111
/** Enable debug mode */
112
debug?: boolean;
113
/** Logger configuration */
114
loggerOptions?: LoggerOptions;
115
}
116
```
117
118
**Basic Configuration Example:**
119
120
```typescript
121
import { Config } from "payload/config";
122
123
const config: Config = {
124
serverURL: "http://localhost:3000",
125
collections: [
126
{
127
slug: "posts",
128
fields: [
129
{
130
name: "title",
131
type: "text",
132
required: true,
133
},
134
{
135
name: "content",
136
type: "richText",
137
},
138
],
139
},
140
],
141
globals: [
142
{
143
slug: "header",
144
fields: [
145
{
146
name: "title",
147
type: "text",
148
},
149
],
150
},
151
],
152
};
153
154
export default config;
155
```
156
157
### Custom Endpoints
158
159
Configuration for custom REST API endpoints that extend Payload's built-in API.
160
161
```typescript { .api }
162
/**
163
* Custom endpoint configuration
164
*/
165
interface Endpoint {
166
/** URL path for the endpoint */
167
path: string;
168
/** HTTP method */
169
method: 'get' | 'head' | 'post' | 'put' | 'patch' | 'delete' | 'connect' | 'options' | string;
170
/** Handler function(s) for the endpoint */
171
handler: PayloadHandler | PayloadHandler[];
172
}
173
174
/**
175
* Payload request handler function
176
*/
177
interface PayloadHandler {
178
(req: PayloadRequest, res: Response, next: NextFunction): void;
179
}
180
```
181
182
**Usage Examples:**
183
184
```typescript
185
const config: Config = {
186
// ... other config
187
endpoints: [
188
{
189
path: '/custom-api',
190
method: 'get',
191
handler: (req, res, next) => {
192
res.json({ message: 'Custom endpoint' });
193
},
194
},
195
{
196
path: '/webhook',
197
method: 'post',
198
handler: [
199
// Multiple handlers can be used
200
authMiddleware,
201
webhookHandler,
202
],
203
},
204
],
205
};
206
```
207
208
### Admin Panel Customization
209
210
Configuration for custom admin panel routes and components.
211
212
```typescript { .api }
213
/**
214
* Custom admin view component type
215
*/
216
type AdminView = React.ComponentType<{
217
user: User;
218
canAccessAdmin: boolean;
219
}>;
220
221
/**
222
* Custom admin route configuration
223
*/
224
interface AdminRoute {
225
/** React component to render */
226
Component: AdminView;
227
/** URL path for the route */
228
path: string;
229
/** Exact path matching (default: false) */
230
exact?: boolean;
231
/** Strict path matching (default: false) */
232
strict?: boolean;
233
}
234
```
235
236
**Usage Examples:**
237
238
```typescript
239
import CustomDashboard from './CustomDashboard';
240
import AnalyticsView from './AnalyticsView';
241
242
const config: Config = {
243
// ... other config
244
admin: {
245
// ... other admin config
246
routes: [
247
{
248
Component: CustomDashboard,
249
path: '/custom-dashboard',
250
exact: true,
251
},
252
{
253
Component: AnalyticsView,
254
path: '/analytics',
255
},
256
],
257
},
258
};
259
```
260
261
### Collection Configuration
262
263
Configuration for content collections (e.g., posts, products, users).
264
265
```typescript { .api }
266
interface CollectionConfig {
267
/** Unique identifier for the collection */
268
slug: string;
269
/** Array of field configurations */
270
fields: Field[];
271
/** Display labels for the collection */
272
labels?: {
273
singular?: string;
274
plural?: string;
275
};
276
/** Admin panel configuration */
277
admin?: CollectionAdminConfig;
278
/** Authentication configuration (makes collection auth-enabled) */
279
auth?: AuthConfig | boolean;
280
/** Access control rules */
281
access?: CollectionAccessConfig;
282
/** Collection-level hooks */
283
hooks?: CollectionHooks;
284
/** File upload configuration */
285
upload?: UploadConfig | boolean;
286
/** Document versioning configuration */
287
versions?: VersionsConfig | boolean;
288
/** Automatic timestamp fields */
289
timestamps?: boolean;
290
/** Database collection name override */
291
dbName?: string;
292
/** Default sort field */
293
defaultSort?: string;
294
/** Disable duplicate checking */
295
disableDuplicate?: boolean;
296
/** GraphQL configuration */
297
graphQL?: {
298
singularName?: string;
299
pluralName?: string;
300
};
301
/** TypeScript configuration */
302
typescript?: {
303
interface?: string;
304
};
305
}
306
307
interface CollectionAdminConfig {
308
/** Default columns to show in list view */
309
defaultColumns?: string[];
310
/** Description shown in admin */
311
description?: string;
312
/** Fields to use for document preview */
313
useAsTitle?: string;
314
/** Custom pagination limit */
315
pagination?: {
316
defaultLimit?: number;
317
limits?: number[];
318
};
319
/** List view configuration */
320
listSearchableFields?: string[];
321
/** Group collections in admin sidebar */
322
group?: string;
323
/** Hide collection from admin */
324
hidden?: boolean;
325
/** Disable create operation in admin */
326
disableCreate?: boolean;
327
/** Disable edit operation in admin */
328
disableEdit?: boolean;
329
/** Disable delete operation in admin */
330
disableDelete?: boolean;
331
/** Custom admin components */
332
components?: {
333
Edit?: React.ComponentType;
334
List?: React.ComponentType;
335
};
336
}
337
```
338
339
**Collection Configuration Example:**
340
341
```typescript
342
const PostsCollection: CollectionConfig = {
343
slug: "posts",
344
labels: {
345
singular: "Post",
346
plural: "Posts",
347
},
348
admin: {
349
defaultColumns: ["title", "status", "createdAt"],
350
useAsTitle: "title",
351
description: "Blog posts and articles",
352
group: "Content",
353
},
354
access: {
355
read: () => true,
356
create: ({ req: { user } }) => !!user,
357
update: ({ req: { user } }) => !!user,
358
delete: ({ req: { user } }) => !!user,
359
},
360
fields: [
361
{
362
name: "title",
363
type: "text",
364
required: true,
365
},
366
{
367
name: "content",
368
type: "richText",
369
required: true,
370
},
371
{
372
name: "status",
373
type: "select",
374
options: [
375
{ label: "Draft", value: "draft" },
376
{ label: "Published", value: "published" },
377
],
378
defaultValue: "draft",
379
},
380
],
381
hooks: {
382
beforeChange: [
383
({ data, operation }) => {
384
if (operation === "create") {
385
data.createdBy = req.user.id;
386
}
387
return data;
388
},
389
],
390
},
391
versions: {
392
drafts: true,
393
maxPerDoc: 10,
394
},
395
timestamps: true,
396
};
397
```
398
399
### Global Configuration
400
401
Configuration for global documents (singleton content like site settings).
402
403
```typescript { .api }
404
interface GlobalConfig {
405
/** Unique identifier for the global */
406
slug: string;
407
/** Array of field configurations */
408
fields: Field[];
409
/** Display label for the global */
410
label?: string;
411
/** Admin panel configuration */
412
admin?: GlobalAdminConfig;
413
/** Access control rules */
414
access?: GlobalAccessConfig;
415
/** Global-level hooks */
416
hooks?: GlobalHooks;
417
/** Document versioning configuration */
418
versions?: VersionsConfig | boolean;
419
/** Automatic timestamp fields */
420
timestamps?: boolean;
421
/** Database collection name override */
422
dbName?: string;
423
/** GraphQL configuration */
424
graphQL?: {
425
name?: string;
426
};
427
/** TypeScript configuration */
428
typescript?: {
429
interface?: string;
430
};
431
}
432
433
interface GlobalAdminConfig {
434
/** Description shown in admin */
435
description?: string;
436
/** Group globals in admin sidebar */
437
group?: string;
438
/** Hide global from admin */
439
hidden?: boolean;
440
/** Custom admin components */
441
components?: {
442
Edit?: React.ComponentType;
443
};
444
}
445
```
446
447
**Global Configuration Example:**
448
449
```typescript
450
const HeaderGlobal: GlobalConfig = {
451
slug: "header",
452
label: "Site Header",
453
admin: {
454
description: "Configure the site header content",
455
group: "Layout",
456
},
457
access: {
458
read: () => true,
459
update: ({ req: { user } }) => user?.role === "admin",
460
},
461
fields: [
462
{
463
name: "logo",
464
type: "upload",
465
relationTo: "media",
466
},
467
{
468
name: "navigation",
469
type: "array",
470
fields: [
471
{
472
name: "label",
473
type: "text",
474
required: true,
475
},
476
{
477
name: "url",
478
type: "text",
479
required: true,
480
},
481
],
482
},
483
],
484
versions: true,
485
};
486
```
487
488
### Access Control Configuration
489
490
Fine-grained access control for collections and globals.
491
492
```typescript { .api }
493
interface CollectionAccessConfig {
494
/** Control who can read documents */
495
read?: AccessFunction;
496
/** Control who can create documents */
497
create?: AccessFunction;
498
/** Control who can update documents */
499
update?: AccessFunction;
500
/** Control who can delete documents */
501
delete?: AccessFunction;
502
/** Control admin panel access */
503
admin?: AccessFunction;
504
}
505
506
interface GlobalAccessConfig {
507
/** Control who can read the global */
508
read?: AccessFunction;
509
/** Control who can update the global */
510
update?: AccessFunction;
511
/** Control admin panel access */
512
admin?: AccessFunction;
513
}
514
515
type AccessFunction = (args: {
516
req: PayloadRequest;
517
data?: any;
518
id?: string;
519
}) => boolean | Promise<boolean> | Where;
520
```
521
522
**Access Control Examples:**
523
524
```typescript
525
// Collection access control
526
const access: CollectionAccessConfig = {
527
// Public read access
528
read: () => true,
529
530
// Only authenticated users can create
531
create: ({ req: { user } }) => !!user,
532
533
// Users can only update their own posts
534
update: ({ req: { user } }) => {
535
if (user?.role === "admin") return true;
536
537
return {
538
author: {
539
equals: user?.id,
540
},
541
};
542
},
543
544
// Only admins can delete
545
delete: ({ req: { user } }) => user?.role === "admin",
546
547
// Admin access based on role
548
admin: ({ req: { user } }) => user?.role === "admin",
549
};
550
551
// Field-level access control
552
const titleField: Field = {
553
name: "title",
554
type: "text",
555
access: {
556
read: () => true,
557
update: ({ req: { user } }) => user?.role === "admin",
558
},
559
};
560
```
561
562
### Hooks Configuration
563
564
Collection and global hooks for extending functionality.
565
566
```typescript { .api }
567
interface CollectionHooks {
568
/** Before operation hooks */
569
beforeOperation?: BeforeOperationHook[];
570
/** Before validation hooks */
571
beforeValidate?: BeforeValidateHook[];
572
/** Before change hooks */
573
beforeChange?: BeforeChangeHook[];
574
/** After change hooks */
575
afterChange?: AfterChangeHook[];
576
/** Before read hooks */
577
beforeRead?: BeforeReadHook[];
578
/** After read hooks */
579
afterReadHook?: AfterReadHook[];
580
/** Before delete hooks */
581
beforeDelete?: BeforeDeleteHook[];
582
/** After delete hooks */
583
afterDelete?: AfterDeleteHook[];
584
/** Auth-specific hooks */
585
beforeLogin?: BeforeLoginHook[];
586
afterLogin?: AfterLoginHook[];
587
afterForgotPassword?: AfterForgotPasswordHook[];
588
}
589
590
type BeforeChangeHook = (args: {
591
data: any;
592
req: PayloadRequest;
593
operation: "create" | "update";
594
originalDoc?: any;
595
}) => any | Promise<any>;
596
597
type AfterChangeHook = (args: {
598
doc: any;
599
req: PayloadRequest;
600
previousDoc?: any;
601
operation: "create" | "update";
602
}) => any | Promise<any>;
603
```
604
605
### Admin Configuration
606
607
Admin panel configuration and customization.
608
609
```typescript { .api }
610
interface AdminConfig {
611
/** Custom bundled admin build */
612
bundler?: Bundler;
613
/** Custom CSS file path */
614
css?: string;
615
/** Custom SCSS file path */
616
scss?: string;
617
/** Date display format */
618
dateFormat?: string;
619
/** Disable admin completely */
620
disable?: boolean;
621
/** Custom login logo */
622
logoBg?: string;
623
/** Custom login view */
624
components?: {
625
Nav?: React.ComponentType;
626
Dashboard?: React.ComponentType;
627
logout?: React.ComponentType;
628
};
629
/** Custom admin meta tags */
630
meta?: {
631
titleSuffix?: string;
632
ogImage?: string;
633
favicon?: string;
634
};
635
/** User collection slug for admin authentication */
636
user?: string;
637
/** Avatar configuration */
638
avatar?: "default" | "gravatar" | React.ComponentType;
639
/** Pagination settings */
640
pagination?: {
641
defaultLimit?: number;
642
limits?: number[];
643
};
644
}
645
```
646
647
## Collection Hook System
648
649
### Hook Types
650
651
Comprehensive hook system for extending collection behavior at different lifecycle stages.
652
653
```typescript { .api }
654
/**
655
* Collection hooks configuration
656
*/
657
interface CollectionHooks {
658
/** Before any operation starts */
659
beforeOperation?: BeforeOperationHook[];
660
/** Before data validation */
661
beforeValidate?: BeforeValidateHook[];
662
/** Before data change (create/update) */
663
beforeChange?: BeforeChangeHook[];
664
/** After data change (create/update) */
665
afterChange?: AfterChangeHook[];
666
/** Before document read */
667
beforeRead?: BeforeReadHook[];
668
/** After document read */
669
afterRead?: AfterReadHook[];
670
/** Before document deletion */
671
beforeDelete?: BeforeDeleteHook[];
672
/** After document deletion */
673
afterDelete?: AfterDeleteHook[];
674
/** After operation error */
675
afterError?: AfterErrorHook;
676
/** Before user login (auth collections only) */
677
beforeLogin?: BeforeLoginHook[];
678
/** After user login (auth collections only) */
679
afterLogin?: AfterLoginHook[];
680
/** After user logout (auth collections only) */
681
afterLogout?: AfterLogoutHook[];
682
/** After "me" operation (auth collections only) */
683
afterMe?: AfterMeHook[];
684
/** After token refresh (auth collections only) */
685
afterRefresh?: AfterRefreshHook[];
686
/** After forgot password (auth collections only) */
687
afterForgotPassword?: AfterForgotPasswordHook[];
688
}
689
690
/**
691
* Hook called before any operation
692
*/
693
type BeforeOperationHook = (args: {
694
/** Operation arguments */
695
args?: any;
696
/** Operation type being performed */
697
operation: 'create' | 'read' | 'update' | 'delete' | 'login' | 'refresh' | 'logout' | 'me' | 'forgotPassword' | 'resetPassword';
698
}) => any;
699
700
/**
701
* Hook called before data validation
702
*/
703
type BeforeValidateHook<T = any> = (args: {
704
/** Document data to be validated */
705
data?: Partial<T>;
706
/** Express request object */
707
req?: PayloadRequest;
708
/** Operation type */
709
operation: 'create' | 'update';
710
/** Original document (for updates) */
711
originalDoc?: T;
712
}) => any;
713
714
/**
715
* Hook called before data changes are saved
716
*/
717
type BeforeChangeHook<T = any> = (args: {
718
/** Document data to be saved */
719
data: Partial<T>;
720
/** Express request object */
721
req: PayloadRequest;
722
/** Operation type */
723
operation: 'create' | 'update';
724
/** Original document (for updates) */
725
originalDoc?: T;
726
}) => any;
727
728
/**
729
* Hook called after data changes are saved
730
*/
731
type AfterChangeHook<T = any> = (args: {
732
/** Saved document */
733
doc: T;
734
/** Express request object */
735
req: PayloadRequest;
736
/** Operation type */
737
operation: 'create' | 'update';
738
/** Original document (for updates) */
739
previousDoc?: T;
740
}) => void;
741
742
/**
743
* Hook called before document read
744
*/
745
type BeforeReadHook = (args: {
746
/** Express request object */
747
req: PayloadRequest;
748
/** Query arguments */
749
query?: any;
750
}) => any;
751
752
/**
753
* Hook called after document read
754
*/
755
type AfterReadHook<T = any> = (args: {
756
/** Read document(s) */
757
doc: T | T[];
758
/** Express request object */
759
req: PayloadRequest;
760
/** Query arguments */
761
query?: any;
762
}) => T | T[];
763
764
/**
765
* Hook called before document deletion
766
*/
767
type BeforeDeleteHook<T = any> = (args: {
768
/** Express request object */
769
req: PayloadRequest;
770
/** Document ID being deleted */
771
id: string | number;
772
/** Document being deleted */
773
doc?: T;
774
}) => void;
775
776
/**
777
* Hook called after document deletion
778
*/
779
type AfterDeleteHook<T = any> = (args: {
780
/** Express request object */
781
req: PayloadRequest;
782
/** Document ID that was deleted */
783
id: string | number;
784
/** Document that was deleted */
785
doc: T;
786
}) => void;
787
788
/**
789
* Authentication-specific hooks
790
*/
791
type BeforeLoginHook<T = any> = (args: {
792
/** Express request object */
793
req: PayloadRequest;
794
/** User attempting to login */
795
user: T;
796
}) => void;
797
798
type AfterLoginHook<T = any> = (args: {
799
/** Express request object */
800
req: PayloadRequest;
801
/** Logged in user */
802
user: T;
803
/** JWT token */
804
token: string;
805
}) => void;
806
807
type AfterLogoutHook<T = any> = (args: {
808
/** Express request object */
809
req: PayloadRequest;
810
/** User that logged out */
811
user?: T;
812
}) => void;
813
```
814
815
**Hook Usage Examples:**
816
817
```typescript
818
// Collection with comprehensive hooks
819
const PostsCollection: CollectionConfig = {
820
slug: "posts",
821
hooks: {
822
// Log all operations
823
beforeOperation: [
824
({ args, operation }) => {
825
console.log(`Starting ${operation} operation`, args);
826
return args;
827
},
828
],
829
830
// Auto-populate author field on create
831
beforeChange: [
832
({ data, req, operation }) => {
833
if (operation === 'create' && req.user) {
834
data.author = req.user.id;
835
data.createdBy = req.user.id;
836
}
837
if (operation === 'update' && req.user) {
838
data.updatedBy = req.user.id;
839
}
840
return data;
841
},
842
],
843
844
// Generate slug from title
845
beforeValidate: [
846
({ data, operation }) => {
847
if ((operation === 'create' || operation === 'update') && data.title && !data.slug) {
848
data.slug = data.title
849
.toLowerCase()
850
.replace(/[^a-z0-9]+/g, '-')
851
.replace(/(^-|-$)/g, '');
852
}
853
return data;
854
},
855
],
856
857
// Clear cache after changes
858
afterChange: [
859
({ doc, operation }) => {
860
console.log(`${operation} completed for post: ${doc.title}`);
861
// Clear cache, send notifications, etc.
862
clearPostCache(doc.id);
863
if (operation === 'create') {
864
sendNewPostNotification(doc);
865
}
866
},
867
],
868
869
// Filter sensitive data from reads
870
afterRead: [
871
({ doc, req }) => {
872
// Remove internal fields for non-admin users
873
if (!req.user || req.user.role !== 'admin') {
874
if (Array.isArray(doc)) {
875
return doc.map(item => ({
876
...item,
877
internalNotes: undefined,
878
adminOnlyField: undefined,
879
}));
880
} else {
881
return {
882
...doc,
883
internalNotes: undefined,
884
adminOnlyField: undefined,
885
};
886
}
887
}
888
return doc;
889
},
890
],
891
892
// Cleanup related data on delete
893
beforeDelete: [
894
async ({ req, id, doc }) => {
895
// Delete related comments
896
await req.payload.delete({
897
collection: 'comments',
898
where: {
899
post: {
900
equals: id,
901
},
902
},
903
});
904
905
// Log deletion
906
console.log(`Deleting post: ${doc?.title} (${id})`);
907
},
908
],
909
910
// Post-deletion cleanup
911
afterDelete: [
912
({ req, id, doc }) => {
913
// Clear caches, update search indexes, etc.
914
clearPostCache(id);
915
updateSearchIndex();
916
console.log(`Post deleted: ${doc.title}`);
917
},
918
],
919
920
// Handle errors
921
afterError: (err, args) => {
922
console.error('Collection operation failed:', err);
923
// Send error to monitoring service
924
sendErrorToMonitoring(err, args);
925
return null;
926
},
927
},
928
fields: [
929
{
930
name: "title",
931
type: "text",
932
required: true,
933
},
934
{
935
name: "slug",
936
type: "text",
937
unique: true,
938
},
939
{
940
name: "author",
941
type: "relationship",
942
relationTo: "users",
943
},
944
],
945
};
946
947
// Auth collection with login hooks
948
const UsersCollection: CollectionConfig = {
949
slug: "users",
950
auth: true,
951
hooks: {
952
// Track login attempts
953
beforeLogin: [
954
({ user, req }) => {
955
console.log(`Login attempt for user: ${user.email}`);
956
// Log to analytics, check for suspicious activity, etc.
957
},
958
],
959
960
// Post-login processing
961
afterLogin: [
962
({ user, req, token }) => {
963
console.log(`User logged in: ${user.email}`);
964
// Update last login timestamp, log activity, send welcome email, etc.
965
updateUserActivity(user.id, 'login');
966
},
967
],
968
969
// Cleanup on logout
970
afterLogout: [
971
({ user, req }) => {
972
if (user) {
973
console.log(`User logged out: ${user.email}`);
974
updateUserActivity(user.id, 'logout');
975
}
976
},
977
],
978
},
979
fields: [
980
{
981
name: "firstName",
982
type: "text",
983
required: true,
984
},
985
{
986
name: "lastName",
987
type: "text",
988
required: true,
989
},
990
],
991
};
992
```
993
994
## Environment Configuration
995
996
Environment variables commonly used with Payload configuration.
997
998
```typescript { .api }
999
// Common environment variables
1000
interface EnvironmentVariables {
1001
/** Database connection string */
1002
DATABASE_URI?: string;
1003
/** Payload secret key */
1004
PAYLOAD_SECRET?: string;
1005
/** Server URL */
1006
PAYLOAD_PUBLIC_SERVER_URL?: string;
1007
/** Email service configuration */
1008
SMTP_HOST?: string;
1009
SMTP_PORT?: string;
1010
SMTP_USER?: string;
1011
SMTP_PASS?: string;
1012
/** File upload configuration */
1013
CLOUDINARY_CLOUD_NAME?: string;
1014
CLOUDINARY_API_KEY?: string;
1015
CLOUDINARY_API_SECRET?: string;
1016
/** Node environment */
1017
NODE_ENV?: "development" | "production" | "test";
1018
}
1019
```
1020
1021
**Environment Configuration Example:**
1022
1023
```typescript
1024
const config: Config = {
1025
serverURL: process.env.PAYLOAD_PUBLIC_SERVER_URL || "http://localhost:3000",
1026
mongoURL: process.env.DATABASE_URI,
1027
secret: process.env.PAYLOAD_SECRET,
1028
email: {
1029
transport: {
1030
host: process.env.SMTP_HOST,
1031
port: parseInt(process.env.SMTP_PORT),
1032
auth: {
1033
user: process.env.SMTP_USER,
1034
pass: process.env.SMTP_PASS,
1035
},
1036
},
1037
fromName: "My Site",
1038
fromAddress: "noreply@mysite.com",
1039
},
1040
};
1041
```