0
# Global Operations
1
2
Operations for managing global documents (singleton content like site settings, navigation, etc.). Globals are perfect for content that appears site-wide and should only have one instance.
3
4
## Capabilities
5
6
### Find Global
7
8
Retrieve a global document by its slug.
9
10
```typescript { .api }
11
/**
12
* Find a global document by slug
13
* @param options - Find global options including slug and configuration
14
* @returns Promise resolving to the global document
15
*/
16
function findGlobal<T>(options: FindGlobalOptions): Promise<T>;
17
18
interface FindGlobalOptions {
19
/** The global slug to find */
20
slug: string;
21
/** How many levels deep to populate relationships */
22
depth?: number;
23
/** Locale for the operation */
24
locale?: string;
25
/** Fallback locale if content not found in specified locale */
26
fallbackLocale?: string;
27
/** User context for access control */
28
user?: User;
29
/** Whether to override access control */
30
overrideAccess?: boolean;
31
/** Whether to include hidden fields */
32
showHiddenFields?: boolean;
33
}
34
```
35
36
**Usage Examples:**
37
38
```typescript
39
import payload from "payload";
40
41
// Find header global
42
const header = await payload.findGlobal({
43
slug: "header",
44
});
45
46
console.log("Site title:", header.title);
47
console.log("Navigation:", header.navigation);
48
49
// Find with populated relationships
50
const headerWithLogos = await payload.findGlobal({
51
slug: "header",
52
depth: 1, // Populate logo uploads
53
});
54
55
// Find with specific locale
56
const frenchHeader = await payload.findGlobal({
57
slug: "header",
58
locale: "fr",
59
fallbackLocale: "en",
60
});
61
62
// Find in Express route with user context
63
app.get("/api/site-settings", async (req, res) => {
64
try {
65
const settings = await payload.findGlobal({
66
slug: "siteSettings",
67
user: req.user,
68
depth: 2,
69
});
70
71
res.json(settings);
72
} catch (error) {
73
res.status(404).json({ error: error.message });
74
}
75
});
76
```
77
78
### Update Global
79
80
Update a global document with new data.
81
82
```typescript { .api }
83
/**
84
* Update a global document
85
* @param options - Update global options including slug, data, and configuration
86
* @returns Promise resolving to the updated global document
87
*/
88
function updateGlobal<T>(options: UpdateGlobalOptions): Promise<T>;
89
90
interface UpdateGlobalOptions {
91
/** The global slug to update */
92
slug: string;
93
/** Updated data for the global */
94
data: any;
95
/** How many levels deep to populate relationships */
96
depth?: number;
97
/** Locale for the operation */
98
locale?: string;
99
/** Fallback locale if content not found in specified locale */
100
fallbackLocale?: string;
101
/** User context for access control */
102
user?: User;
103
/** Whether to override access control */
104
overrideAccess?: boolean;
105
/** Whether to include hidden fields */
106
showHiddenFields?: boolean;
107
}
108
```
109
110
**Usage Examples:**
111
112
```typescript
113
// Update header global
114
const updatedHeader = await payload.updateGlobal({
115
slug: "header",
116
data: {
117
title: "New Site Title",
118
tagline: "Updated tagline",
119
navigation: [
120
{ label: "Home", url: "/" },
121
{ label: "About", url: "/about" },
122
{ label: "Contact", url: "/contact" },
123
],
124
},
125
});
126
127
// Update with file uploads
128
const updatedSettings = await payload.updateGlobal({
129
slug: "siteSettings",
130
data: {
131
siteName: "My Updated Site",
132
logo: logoFileId, // ID of uploaded logo
133
socialMedia: {
134
twitter: "@mysite",
135
facebook: "mysite",
136
},
137
},
138
depth: 1, // Return populated logo
139
});
140
141
// Update with specific locale
142
const frenchFooter = await payload.updateGlobal({
143
slug: "footer",
144
data: {
145
copyright: "© 2023 Mon Site. Tous droits réservés.",
146
legalLinks: [
147
{ label: "Mentions légales", url: "/mentions-legales" },
148
{ label: "Politique de confidentialité", url: "/confidentialite" },
149
],
150
},
151
locale: "fr",
152
});
153
154
// Partial update in Express route
155
app.put("/api/site-settings", async (req, res) => {
156
try {
157
const updated = await payload.updateGlobal({
158
slug: "siteSettings",
159
data: req.body, // Partial update data
160
user: req.user,
161
});
162
163
res.json(updated);
164
} catch (error) {
165
res.status(400).json({ error: error.message });
166
}
167
});
168
```
169
170
## Global Configuration
171
172
### Basic Global Setup
173
174
Globals are configured similarly to collections but represent singleton documents.
175
176
```typescript { .api }
177
interface GlobalConfig {
178
/** Unique identifier for the global */
179
slug: string;
180
/** Array of field configurations */
181
fields: Field[];
182
/** Display label for the global */
183
label?: string;
184
/** Admin panel configuration */
185
admin?: GlobalAdminConfig;
186
/** Access control rules */
187
access?: GlobalAccessConfig;
188
/** Global-level hooks */
189
hooks?: GlobalHooks;
190
/** Document versioning configuration */
191
versions?: VersionsConfig | boolean;
192
/** Automatic timestamp fields */
193
timestamps?: boolean;
194
/** Database collection name override */
195
dbName?: string;
196
/** GraphQL configuration */
197
graphQL?: {
198
name?: string;
199
};
200
/** TypeScript configuration */
201
typescript?: {
202
interface?: string;
203
};
204
}
205
```
206
207
**Global Configuration Examples:**
208
209
```typescript
210
// Site header global
211
const HeaderGlobal: GlobalConfig = {
212
slug: "header",
213
label: "Site Header",
214
admin: {
215
description: "Configure the site header content and navigation",
216
group: "Layout",
217
},
218
access: {
219
read: () => true, // Public read access
220
update: ({ req: { user } }) => user?.role === "admin",
221
},
222
fields: [
223
{
224
name: "title",
225
type: "text",
226
required: true,
227
admin: {
228
description: "Main site title displayed in header",
229
},
230
},
231
{
232
name: "logo",
233
type: "upload",
234
relationTo: "media",
235
admin: {
236
description: "Site logo image",
237
},
238
},
239
{
240
name: "navigation",
241
type: "array",
242
label: "Navigation Links",
243
minRows: 1,
244
maxRows: 10,
245
fields: [
246
{
247
name: "label",
248
type: "text",
249
required: true,
250
},
251
{
252
name: "url",
253
type: "text",
254
required: true,
255
},
256
{
257
name: "newTab",
258
type: "checkbox",
259
defaultValue: false,
260
},
261
],
262
},
263
],
264
versions: {
265
drafts: true,
266
},
267
};
268
269
// Site settings global
270
const SiteSettingsGlobal: GlobalConfig = {
271
slug: "siteSettings",
272
label: "Site Settings",
273
admin: {
274
description: "General site configuration and settings",
275
group: "Configuration",
276
},
277
fields: [
278
{
279
name: "general",
280
type: "group",
281
label: "General Settings",
282
fields: [
283
{
284
name: "siteName",
285
type: "text",
286
required: true,
287
},
288
{
289
name: "siteDescription",
290
type: "textarea",
291
maxLength: 160,
292
},
293
{
294
name: "favicon",
295
type: "upload",
296
relationTo: "media",
297
},
298
],
299
},
300
{
301
name: "social",
302
type: "group",
303
label: "Social Media",
304
fields: [
305
{
306
name: "twitter",
307
type: "text",
308
},
309
{
310
name: "facebook",
311
type: "text",
312
},
313
{
314
name: "instagram",
315
type: "text",
316
},
317
],
318
},
319
{
320
name: "analytics",
321
type: "group",
322
label: "Analytics",
323
fields: [
324
{
325
name: "googleAnalyticsId",
326
type: "text",
327
},
328
{
329
name: "facebookPixelId",
330
type: "text",
331
},
332
],
333
},
334
],
335
hooks: {
336
afterChange: [
337
({ doc, req }) => {
338
// Clear cache when settings change
339
req.payload.logger.info("Site settings updated, clearing cache");
340
},
341
],
342
},
343
};
344
345
// Footer global with localization
346
const FooterGlobal: GlobalConfig = {
347
slug: "footer",
348
label: "Site Footer",
349
admin: {
350
description: "Configure footer content and links",
351
group: "Layout",
352
},
353
fields: [
354
{
355
name: "copyright",
356
type: "text",
357
required: true,
358
localized: true,
359
},
360
{
361
name: "links",
362
type: "array",
363
label: "Footer Links",
364
fields: [
365
{
366
name: "group",
367
type: "text",
368
required: true,
369
localized: true,
370
},
371
{
372
name: "links",
373
type: "array",
374
fields: [
375
{
376
name: "label",
377
type: "text",
378
required: true,
379
localized: true,
380
},
381
{
382
name: "url",
383
type: "text",
384
required: true,
385
},
386
],
387
},
388
],
389
},
390
{
391
name: "newsletter",
392
type: "group",
393
label: "Newsletter Signup",
394
fields: [
395
{
396
name: "enabled",
397
type: "checkbox",
398
defaultValue: false,
399
},
400
{
401
name: "title",
402
type: "text",
403
localized: true,
404
admin: {
405
condition: (data, siblingData) => siblingData?.enabled,
406
},
407
},
408
{
409
name: "description",
410
type: "textarea",
411
localized: true,
412
admin: {
413
condition: (data, siblingData) => siblingData?.enabled,
414
},
415
},
416
],
417
},
418
],
419
versions: true,
420
timestamps: true,
421
};
422
```
423
424
## Common Global Use Cases
425
426
### Site Configuration
427
428
Globals are perfect for site-wide configuration that needs to be easily editable:
429
430
```typescript
431
// SEO defaults global
432
const SEODefaultsGlobal: GlobalConfig = {
433
slug: "seoDefaults",
434
label: "SEO Defaults",
435
fields: [
436
{
437
name: "title",
438
type: "text",
439
required: true,
440
},
441
{
442
name: "description",
443
type: "textarea",
444
maxLength: 160,
445
},
446
{
447
name: "ogImage",
448
type: "upload",
449
relationTo: "media",
450
},
451
{
452
name: "twitterHandle",
453
type: "text",
454
},
455
],
456
};
457
458
// Theme settings global
459
const ThemeSettingsGlobal: GlobalConfig = {
460
slug: "themeSettings",
461
label: "Theme Settings",
462
fields: [
463
{
464
name: "colorScheme",
465
type: "select",
466
options: [
467
{ label: "Light", value: "light" },
468
{ label: "Dark", value: "dark" },
469
{ label: "Auto", value: "auto" },
470
],
471
defaultValue: "light",
472
},
473
{
474
name: "primaryColor",
475
type: "text",
476
defaultValue: "#007bff",
477
},
478
{
479
name: "fonts",
480
type: "group",
481
fields: [
482
{
483
name: "heading",
484
type: "text",
485
defaultValue: "Inter",
486
},
487
{
488
name: "body",
489
type: "text",
490
defaultValue: "Inter",
491
},
492
],
493
},
494
],
495
};
496
```
497
498
### Usage in Frontend Applications
499
500
```typescript
501
// Next.js example - fetch global data
502
export async function getStaticProps() {
503
const header = await payload.findGlobal({
504
slug: "header",
505
depth: 1,
506
});
507
508
const siteSettings = await payload.findGlobal({
509
slug: "siteSettings",
510
});
511
512
return {
513
props: {
514
header,
515
siteSettings,
516
},
517
revalidate: 300, // Revalidate every 5 minutes
518
};
519
}
520
521
// React component using global data
522
function Layout({ children, header, siteSettings }) {
523
return (
524
<html>
525
<head>
526
<title>{siteSettings.general.siteName}</title>
527
<meta name="description" content={siteSettings.general.siteDescription} />
528
<link rel="icon" href={siteSettings.general.favicon?.url} />
529
</head>
530
<body>
531
<header>
532
<img src={header.logo?.url} alt={header.title} />
533
<nav>
534
{header.navigation.map((item, index) => (
535
<a
536
key={index}
537
href={item.url}
538
target={item.newTab ? "_blank" : "_self"}
539
>
540
{item.label}
541
</a>
542
))}
543
</nav>
544
</header>
545
546
<main>{children}</main>
547
548
<footer>
549
<p>{footer.copyright}</p>
550
</footer>
551
</body>
552
</html>
553
);
554
}
555
```