or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdconfiguration.mdcore-operations.mdfield-types.mdglobal-operations.mdindex.mdpreferences.mdversion-control.md

global-operations.mddocs/

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

```