Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.
AuthorNick Vogel

How to build a header navigation using Payload Globals

Community Guide
AuthorNick Vogel

In this guide, we'll show off the power and flexibility of Payload Globals by creating a header navigation as an example.

Payload Globals are very similar to Payload Collections. The primary difference is that Collections allow you to create many of the same type of document multiple times. A Global, however, corresponds to a single document. Just like Collections, you’re able to create as many Globals as you need, but none of them will create more than one document.

Globals are stored in your database and have the same fields available to it as Collections do.

Similarly to Collections, Globals also automatically generates Local API, REST API, and GraphQL API to query your documents on the frontend.

You’ll use Globals for things like header and footer navigation or site-wide banners (like a sticky banner). 

So let’s create a header navigation as an example.

To get started, you’ll want to create a new directory structure in your app, with a config.ts file inside, as follows:

1
src/
2
├── globals/
3
│ └── header/
4
│ └── config.ts

Next, you'll import import {GlobalConfig} from ‘payload’ at the top of the file, and export a const called Header and assign the GlobalConfig type to it. 

You’ll set it equal to an object with the slug and fields options, use 'header' for the slug and an empty array for your fields.

1
import { GlobalConfig } from 'payload'
2
3
export const Header: GlobalConfig = {
4
slug: 'header',
5
fields: [
6
7
]
8
}

From there, you can import this into your payload config file by adding it to your globals array as follows:

1
globals: [Header],

If you’d like to call the Global something else, you can use the label option to change how it’s displayed in the admin dashboard navigation (i.e. label: ‘Header Nav’,). You’ll still query the global by its slug on the frontend, but you can change the name just like you can for a Collection.

Slug and fields are both required in order to initialize a global, but once you have those set, that’s all you really need.

So, we’ll create an array of links for our Header. We can create a new field with type: array and name: headerLinks. In this array, we’ll include an array of fields with a name, destination (which will be a relationship field), and a newTab checkbox. We’ll set the array to have a minRow of 1 and a maxRow of 5, just so our Header nav doesn’t get out of hand.

1
export const Header: GlobalConfig = {
2
slug: 'header',
3
fields: [
4
{
5
type: 'array',
6
name: 'headerLinks',
7
fields: [
8
{
9
name: 'destination',
10
type: 'relationship',
11
relationTo: 'posts',
12
},
13
{
14
name: 'newTab',
15
label: 'Open in a new tab?',
16
type: 'checkbox',
17
}
18
],
19
minRows: 1,
20
maxRows: 5
21
}
22
]
23
}

Now we can use each array item to define our navigation menu in the admin panel.

Just like our Collections, you have access to the access, admin, and description options, but you cannot set a global to be your upload collection nor use it for authentication.

Access

I won’t spend too much time here because access in Globals is limited to read and update options (there is no create or delete as globals do not create more than one document). If you only want someone to be able to read the header, you’d set it to: 

1
export const Header: GlobalConfig = {
2
slug: 'header',
3
access: {
4
read: (): boolean => true,
5
},
6
};

Admin

While many of the admin options are similar between Collections and Globals, there are a few key differences. You can still use group to group your global in the admin UI. So for example, we can set group to navigation to get it into its own group, where we might put our footer navigation as well.

1
export const Header: GlobalConfig = {
2
slug: 'header',
3
access: {
4
read: (): boolean => true,
5
},
6
admin: {
7
group: 'Navigation',
8
},

You can also set hidden to true or use a function that takes user as an argument to either hide the global from navigation or from specific users.

1
export const Header: GlobalConfig = {
2
slug: 'header',
3
access: {
4
read: (): boolean => true,
5
},
6
admin: {
7
group: 'Navigation',
8
hidden: true, // this will remove it from the admin UI
9
},

Description

Just like Collections, you can set this as a text or React component to provide more information to editors about what this global does.

1
export const Header: GlobalConfig = {
2
slug: 'header',
3
access: {
4
read: (): boolean => true,
5
},
6
admin: {
7
group: 'Navigation',
8
description: 'This is our header navigation', // Now visible on the global view.
9
},

Conclusion

Globals are by their nature less complicated than Collections.

Since they use many of the same options as Collections but without the added complexity of multiple documents, it’s much easier to manage and add to Globals than it would be for Collections. 

However, Globals add a layer of powerful flexibility that allows you to set up things like header and footer navigation and site-wide notifications.