Custom Globals in Payload CMS
A Global in Payload is a singleton configuration record that exists in a single instance: site settings, navigation menu, footer, SEO defaults. Unlike collections, globals have no list of documents — just one editable record.
Basic Global
// globals/Settings.ts
import { GlobalConfig } from 'payload/types'
const Settings: GlobalConfig = {
slug: 'settings',
label: 'Site Settings',
access: {
read: () => true,
update: ({ req: { user } }) => user?.role === 'admin',
},
fields: [
{
name: 'siteName',
type: 'text',
required: true,
label: 'Site Name',
},
{
name: 'logo',
type: 'upload',
relationTo: 'media',
},
{
name: 'contactEmail',
type: 'email',
},
{
name: 'socialLinks',
type: 'array',
fields: [
{
name: 'platform',
type: 'select',
options: ['telegram', 'vk', 'youtube', 'instagram'],
},
{ name: 'url', type: 'text' },
],
},
{
name: 'defaultSeo',
type: 'group',
label: 'Default SEO',
fields: [
{ name: 'title', type: 'text' },
{ name: 'description', type: 'textarea' },
{ name: 'ogImage', type: 'upload', relationTo: 'media' },
],
},
],
}
export default Settings
Navigation Global with Nested Links
// globals/Navigation.ts
const Navigation: GlobalConfig = {
slug: 'navigation',
fields: [
{
name: 'items',
type: 'array',
fields: [
{ name: 'label', type: 'text', required: true },
{
name: 'link',
type: 'group',
fields: [
{
name: 'type',
type: 'radio',
options: ['internal', 'external'],
defaultValue: 'internal',
},
{
name: 'page',
type: 'relationship',
relationTo: 'pages',
admin: { condition: (_, { type }) => type === 'internal' },
},
{
name: 'url',
type: 'text',
admin: { condition: (_, { type }) => type === 'external' },
},
],
},
{
name: 'children',
type: 'array',
fields: [
{ name: 'label', type: 'text' },
{ name: 'page', type: 'relationship', relationTo: 'pages' },
],
},
],
},
],
}
Reading Global in Next.js
// app/(frontend)/layout.tsx
import { getPayload } from 'payload'
import config from '@payload-config'
export default async function RootLayout({ children }) {
const payload = await getPayload({ config })
const settings = await payload.findGlobal({ slug: 'settings' })
const navigation = await payload.findGlobal({ slug: 'navigation' })
return (
<html>
<body>
<Header nav={navigation} logo={settings.logo} />
<main>{children}</main>
<Footer settings={settings} />
</body>
</html>
)
}
REST API for Globals
# Get
GET /api/globals/settings
# Update (requires permissions)
POST /api/globals/settings
Authorization: Bearer <token>
Globals Versioning
const Settings: GlobalConfig = {
slug: 'settings',
versions: { drafts: true },
// ...
}
Timeline
Configuring 2–4 globals (settings, navigation, footer, SEO) — 1 day including frontend integration.







