All Blog Articles

Building Dynamic Websites with Payload and NextJS: A Comprehensive Guide

Media
Sandro WegmannMay 20, 2025
Learn to build flexible, content-driven websites with Payload CMS, NextJS, and TailwindCSS in this comprehensive development guide.

In today's digital landscape, creating dynamic websites is more important than ever. This guide will walk you through the process of building dynamic websites using Payload NextJS. We will cover how to set up Tailwind CSS, create a pages collection, and implement a header and footer for your website. This tutorial is based on insights from the AllAboutPayload YouTube channel, which provides valuable resources for developers interested in Payload and NextJS.

This article provides a detailed written step-by-step tutorial based on our comprehensive video guide available on YouTube at https://www.youtube.com/watch?v=8BXT64lnTXc. For visual learners or those who prefer following along with video instruction, the YouTube tutorial covers the same content while offering additional context and real-time demonstrations of each implementation step in the process.


Table of Contents


Understanding the Backend Structure

Before diving into the implementation, let's briefly discuss the backend structure of our project. The project consists of several collections, primarily focusing on user management and media storage.

  • User Collection: This collection manages access to the Payload admin panel.
  • Media Collection: This collection allows for uploads, storing images and videos on AWS S3, which is integrated through a dedicated plugin.
  • Pages Collection: Each page in our application will have a name, a slug, and a layout composed of blocks. This structure is reminiscent of the Gutenberg editor used in WordPress, where each page can be built using different components.

In addition to the pages, we will have a global header and footer that will be consistent across all pages. This keeps our design uniform and allows for easy updates in the future.

payload-cms-backend-structure-diagram.jpg


Setting Up Tailwind CSS

To enhance the styling of our website, we will be using Tailwind CSS. The first step is to create a root layout where we can import our Tailwind CSS styles. This layout will be essential for both the frontend and the Payload backend.

  1. Create a file named layout.tsx in your app directory.
  2. Paste in the boilerplate code provided in the official Tailwind CSS Next.js installation guide.

After setting up the layout, we will install the necessary dependencies for Tailwind CSS. Using pnpm, run the command to install the packages:

pnpm install -D tailwindcss postcss autoprefixer

Next, initialize Tailwind CSS:

pnpx tailwindcss init -p

This command will create two configuration files: tailwind.config.js and postcss.config.js. Now, we need to specify the content sources in the Tailwind config file:

content: ['./app/**/*.{js,ts,jsx,tsx}']

Finally, create a global CSS file to include Tailwind's layers and import it in your layout:

import './styles/globals.css'


Creating the Pages Collection

Now that we have Tailwind CSS set up, the next step is to create a pages collection. This will allow us to manage the content dynamically.

To create the pages collection:

  1. Create a new file named pages.ts in your collections directory.
  2. Add the following code to define the collection:
export const pages = {
    slug: 'pages',
    fields: [
        {
            name: 'name',
            type: 'text',
            required: true,
        },
        {
            name: 'slug',
            type: 'text',
            required: true,
            admin: {
                position: 'sidebar',
            },
        },
        {
            name: 'layout',
            type: 'blocks',
            blocks: [],
        },
    ],
};


With this setup, each page will have a unique name and slug. The layout will be an array of blocks, which we will define later.


Next, we will implement a global header and footer for our website. This will involve creating schemas for both components.

  1. Create a new directory named globals in your project.
  2. Create header.ts and footer.ts files in the globals directory.

In header.ts, define the schema as follows:

export const header = {
    slug: 'header',
    fields: [
        {
            name: 'logo',
            type: 'upload',
            relationTo: 'media',
            required: true,
        },
        {
            name: 'nav',
            type: 'array',
            required: true,
            minRows: 1,
            fields: [
                {
                    name: 'label',
                    type: 'text',
                },
                {
                    name: 'link',
                    type: 'text',
                },
            ],
        },
    ],
};


In footer.ts, define a similar schema, but include a copyright notice:

export const footer = {
    slug: 'footer',
    fields: [
        {
            name: 'logo',
            type: 'upload',
            relationTo: 'media',
            required: true,
        },
        {
            name: 'copyright',
            type: 'text',
            required: true,
        },
    ],
};


Rendering Pages in the Frontend

Now that we have our header and footer set up, the next step is to render our pages in the frontend. This will involve creating dynamic routes.

In your website folder, create another folder named [slug] and inside it, create a page.tsx file. This file will handle the dynamic routing based on the slug provided.

Add the following code to page.tsx:

import { useRouter } from 'next/router';

const Page = () => {
    const router = useRouter();
    const { slug } = router.query;

    // Fetch the page data using the slug here

    return (
        {/* Render the page content here */}
    );
};

export default Page;
payload-cms-admin-page-editor-interface.jpg


Creating Block Schemas

To provide more flexibility in our layouts, we will create block schemas for different types of content. These include a cover block, a rich text block, and an image block.

  1. Create a new folder named blocks in your project.
  2. Inside the blocks folder, create the following files:
    • cover.ts
    • richText.ts
    • image.ts


Define the cover block schema:

export const cover = {
    slug: 'cover',
    fields: [
        {
            name: 'title',
            type: 'text',
            required: true,
        },
        {
            name: 'subtitle',
            type: 'text',
            required: true,
        },
    ],
};


Define the rich text block schema:

export const richText = {
    slug: 'richText',
    fields: [
        {
            name: 'content',
            type: 'richText',
            required: true,
        },
    ],
};


Define the image block schema:

export const image = {
    slug: 'image',
    fields: [
        {
            name: 'image',
            type: 'upload',
            relationTo: 'media',
            required: true,
        },
    ],
};


Deploying to Vercel

With everything set up, the final step is to deploy your project to Vercel. This process is straightforward:

  1. Commit all your changes and push them to your repository.
  2. Go to your Vercel dashboard and create a new project.
  3. Import your repository and set up the environment variables needed for your project.
  4. Click on deploy, and within a few minutes, your project should be live!

Make sure to test your deployed site to verify everything is functioning as expected.


Frequently Asked Questions

What is Payload?

Payload is a headless CMS built with Node.js, offering flexibility and a powerful admin panel for managing content.

What is NextJS?

NextJS is a React framework that enables server-side rendering and static site generation, enhancing the performance of web applications.

How does Tailwind CSS improve my project?

Tailwind CSS provides utility-first CSS classes, allowing for rapid styling without leaving your HTML markup.

Can I use Payload with other frontend frameworks?

Yes, Payload is designed to be flexible and can be integrated with various frontend frameworks, though this guide focuses on NextJS.

By following this guide, you will have a solid foundation for building dynamic websites using Payload NextJS. Don't forget to explore more resources on the AllAboutPayload website for deeper insights and updates.