Embed Payload CMS 3.0 Admin UI in Your Next.js App

This tutorial demonstrates how to integrate Payload CMS 3.0 beta with a Next.js application and embed the Payload CMS Admin UI within your Next.js web application.

Payload CMS is a versatile, open-source headless content management system (CMS) built with Node.js, Express, and MongoDB. It allows developers to manage and structure content with ease, offering a robust and extendable backend that integrates seamlessly with various front-end frameworks.

The Admin UI is a powerful interface provided by Payload CMS, enabling content managers to easily create, manage, and organize content. It provides a user-friendly interface with rich text editing, media management, and custom field types to cater to different content needs.

Setting Up Your Next.js App

First, ensure you have a Next.js app set up. If not, you can create one using the following command:

npx create-next-app@latest

During setup, select the recommended options:

  • Project name: my-nextjs-app
  • Use TypeScript: Yes
  • Use ESLint: Yes
  • Use src/ directory: Yes
  • Use App Router (recommended): Yes

Installing and Configuring Payload CMS 3.0 Beta

Add Payload CMS to your Next.js app with a single command:

npx create-payload-app@beta
This command sets up a payload folder with all necessary configurations and files.

Understanding the payload.config.ts File

The payload.config.js file is the main configuration file for Payload CMS. This file defines collections, globals, plugins, and other configurations necessary for your Payload CMS instance.

Essentials in payload.config.ts:

Admin Section: Defines the settings related to the admin panel.
Collections: Sets up different content types that you can manage.
Plugins: Additional functionalities/plugins to extend the capabilities of Payload CMS.

Here is a simple version of the payload.config.ts file focusing on the essential parts:

import { postgresAdapter } from '@payloadcms/db-postgres';
import { buildConfig } from 'payload';
import { Users } from './collections/Users';

export default buildConfig({
  admin: {
    user: Users.slug,
    avatar: 'default',
  },
  collections: [
    Users,
    // ... additional collections
  ],
  plugins: [
    // ... additional plugins
  ],
  secret: process.env.PAYLOAD_SECRET || '',
  typescript: {
    outputFile: path.resolve(__dirname, 'payload-types.ts'),
  },
  db: postgresAdapter({
    pool: {
      connectionString: process.env.DATABASE_URI || '',
    },
  }),
});

Setting Up Shared Root Layout

Create a shared root layout to include the required UI components:


// src/shared-root-layout.tsx
import { ReactNode } from 'react';
import { StyledEngineProvider } from '@mui/material/styles';
import { CssBaseline } from '@mui/material';
import { ThemeProvider } from '@emotion/react';  // make sure you have a theme configured
import AppRouterCacheProvider from 'next/app';   // assuming this is your setup
import theme from './theme';  // path to your MUI theme

const SharedRootLayout = ({ children }: { children: ReactNode }) => {
  return (
    <html>
      <head></head>
      <body>
        <StyledEngineProvider injectFirst={true}>
          <AppRouterCacheProvider options={{ enableCssLayer: true }}>
            <ThemeProvider theme={theme}>
              <CssBaseline />
              {children}
            </ThemeProvider>
          </AppRouterCacheProvider>
        </StyledEngineProvider>
      </body>
    </html>
  );
{;

export default SharedRootLayout;

Embedding the Admin UI

First, create a layout and admin page under the payload-admin folder to embed the Payload CMS Admin UI.

Then create a layout file: src/app/payload-admin/PayloadAdminLayout.tsx


// src/app/payload-admin/PayloadAdminLayout.tsx
import { Box } from '@mui/material';
import SharedRootLayout from '../shared-root-layout';

export default function PayloadAdminLayout({ children }: { children: React.ReactNode }) {
  return (
    <SharedRootLayout>
      <Box sx={{ width: '100%', display: 'flex', justifyContent: 'center' }}>
        <header>Admin Header</header>
      </Box>
      <main style={{ width: '100%' }}>{children}</main>
    </SharedRootLayout>
  );
}

Create an admin page: src/app/payload-admin/PayloadAdminPage.tsx


// src/app/payload-admin/PayloadAdminPage.tsx
import Head from 'next/head';

const PayloadAdminPage = () => {
  return (
    <div style={{ height: '100vh' }}>
      <Head>
        <title>Admin Panel</title>
      </Head>
      <iframe
        src="/adm"  // Ensure this points to the correct URL for your Payload admin UI
        style={{ width: '100%', height: '100%', border: 'none' }}
      />
    </div>
  );
};

export default PayloadAdminPage;

Testing and Verifying

Run your Next.js app:

npm run dev

Visit your Next.js app at {APP_URL}/admin. You should see the Payload Admin UI embedded within your Next.js application.

A Robust Solution for Content Management

Integrating Payload CMS with a Next.js application provides a robust solution for content management. By embedding the Admin UI directly within your Next.js app, you can offer a seamless user experience for content editors and admins. With Payload CMS’s flexibility and Next.js’s power, you can build advanced, content-driven applications easily.

Conversation

Join the conversation

Your email address will not be published. Required fields are marked *