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.

White Label the Admin UI

Published On
White Label the Admin UI
White Label the Admin UI

Easily make Payload the perfect white labeled headless CMS. With Payload, you get complete control of the look and feel of the Admin Panel.

Across the Admin UI, the branding from Payload is minimal so that the focus stays where it should be—on your application. By updating the Payload branding, you can create a customized interface and your client (or team, or whoever will access your admin panel) will be greeted with a dynamic interface that is consistent with your application branding.

In this blog post, you will learn how to rebrand and white label the Payload admin panel for your application by modifying the following elements:

  • Favicon
  • Title
  • ogImage
  • Icon
  • Logo

Get Started

You can use your own Payload app or start a new one for this tutorial. If you haven't started a project yet, you can get set up easily by running npx create-payload-app in your terminal.

For more details on how to start an application, including how to do so from scratch, read the installation documentation.

Payload Config

Start by navigating to your base Payload config file in which all options for the Admin panel are defined.

Below is an example config file:

1
import { buildConfig } from 'payload/config';
2
import dotenv from 'dotenv';
3
import Page from './collections/Page';
4
import Media from './collections/Media';
5
6
dotenv.config();
7
8
export default buildConfig({
9
serverURL: process.env.PAYLOAD_PUBLIC_SERVER_URL,
10
collections: [
11
Page,
12
Media,
13
],
14
});

Admin Option

Next, add the admin option to your payload config file this can start as an empty object.

1
export default buildConfig({
2
serverURL: process.env.PAYLOAD_PUBLIC_SERVER_URL,
3
admin: {},
4
collections: [
5
Page,
6
Media,
7
],
8
});

Meta

The admin property takes the following sub-properties:

titleSuffix: Text that appends the meta/page title displayed in the browser tab—must be a string.

favicon: Image that will be displayed as the tab icon.

ogImage: Image that will appear in the preview when you share links to your admin panel online and through social media.

Now, let’s add the meta-object and the above properties.

1
export default buildConfig({
2
serverURL: process.env.PAYLOAD_PUBLIC_SERVER_URL,
3
admin: {
4
meta: {
5
titleSuffix: '- TRBL Design',
6
favicon: '/assets/favicon.svg',
7
ogImage: '/assets/logo.svg',
8
},
9
},
10
collections: [
11
Page,
12
Media,
13
],
14
});

Serving Images

We need to ensure the images are served somewhere they can be downloaded by the browser. We could have saved an absolute URL if the assets are hosted somewhere. Instead of that we set relative paths to an assets folder for favicon.svg and logo.svg above; we can serve them from the same express app as Payload is using. Create a directory called assets and save your images there.

Then in your server.js or wherever you have defined express routes, add the line that serves /assets with express.static:

1
import express from 'express';
2
import path from 'path';
3
4
const app = express();
5
app.use('/assets', express.static(path.resolve(__dirname, './assets')));
6
7
payload.init({
8
secret: process.env.PAYLOAD_SECRET_KEY,
9
mongoURL: process.env.MONGO_URL,
10
express: app,
11
license: process.env.PAYLOAD_LICENSE_KEY,
12
});
13
14
app.listen(process.env.PORT);

At this point, if we check out our app in the browser—the tab will display your updated favicon and title suffix.

Payload CMS Metadata Screenshot

To test that the ogImage has successfully updated, use the browser inspector to view the metadata or test your app through your social media of choice or a web developer tool e.g. Twitter’s Card Validator.

Custom Components

In addition to metadata, the admin option also takes custom components to override the default configuration.

The properties we are interested in for rebranding the admin panel are:

graphics.Logo: Image component to be displayed as the logo on the Sign Up / Login view.

graphics.Icon: Image component displayed above the Nav in the admin panel, often a condensed version of a full logo.

Now let's set up these custom components:

  • Add components and open an object
  • Within components, add the graphics property and open another object
  • Now we can point to the relevant files for the Logo and Icon
1
import Logo from './graphics/Logo';
2
import Icon from './graphics/Icon';
3
4
dotenv.config();
5
6
export default buildConfig({
7
serverURL: process.env.PAYLOAD_PUBLIC_SERVER_URL,
8
admin: {
9
meta: {
10
titleSuffix: '- Custom Title',
11
favicon: '/assets/favicon.svg',
12
ogImage: '/assets/logo.svg',
13
},
14
components: {
15
graphics: {
16
Logo,
17
Icon,
18
},
19
},
20
},
21
collections: [
22
Page,
23
Media,
24
],
25
});

These graphics need to be React components that can render whatever you'd like. They could render img tags or full React SVGs. In this example, we're going to include images, css and other html too.

1
import React from 'react';
2
import './logo.scss';
3
4
export const Logo = () => (
5
<div className="logo">
6
<img
7
src="/assets/logo.png"
8
alt="TRBL Design Logo"
9
/>
10
</div>
11
);

Optionally we can include some styling too.

1
.logo {
2
img {
3
max-height: 200px;
4
margin: auto;
5
}
6
7
h1 {
8
margin: 3rem auto;
9
text-align: center;
10
}
11
}

Final step, let’s check out the new logo and icons.

Payload CMS White Label Branded Login
Payload CMS White Label Branded Dashboard

Summary

There you have it! With around 10 lines of code you can brand the admin panel, update metadata and add custom components to effectively white label the admin panel for your clients or users.

Payload gives you the freedom and control to customize other aspects too, like the swapping out the Dashboard or creating custom inputs, to learn more about the admin panel and custom components—check out the pages below.

Read More

Questions or Comments?

Join us on GitHub discussions.