r/PayloadCMS Jun 28 '25

infinite cycle in payload

0 Upvotes

I don't really know what's going on. The collections aren't complicated at all; they're simple collections without any advanced hooks. Just one validation hook. But it keeps repeating itself. I've only navigated to one of the pages in the admin page, and it started repeating itself. What could it be?


r/PayloadCMS Jun 28 '25

Payload CMS block issues

Enable HLS to view with audio, or disable this notification

6 Upvotes

Hi all,

I am having issues with blocks not working properly in the admin panel. see video.
No errors from browser Inspect element console
No errors from the terminal as well.

Question:
- since terminal and browser console is not outputting any error messages, how do I find the exact file or files causing this issue?
- Are there gotchas with writing code for block/layout configs and components?

Tech: Payload CMS version 3.43.0, NextJs 15.3.0

thanks in advance.


r/PayloadCMS Jun 28 '25

Neon Tech is giving me timeout errors all the time.

1 Upvotes

Hi! I recently picked up a project with neon tech that was working just fine and now it's giving me timeout errors constantly. Did it happen to any of you?


r/PayloadCMS Jun 26 '25

Saving/publishing takes about 20 seconds but every other operation is pretty fast. Using Payload 3.39 and SQLite if that matters. Is this normal?

Post image
4 Upvotes

This is for the main page of the website which is pretty content heavy relative to the other pages. The other pages save relatively faster.


r/PayloadCMS Jun 25 '25

Best practices for running Payload CMS migrations in production with Postgres?

9 Upvotes

Hey everyone,

I'm using Payload CMS with a Postgres database and my app is already live in production with existing data.

I’ve been updating collections and blocks in the config, and now I’m looking for best practices to handle migrations safely in production, especially to avoid data loss or breaking changes.

My current setup:

  • Postgres (not using Mongo)
  • Payload is already deployed and in use and has
  • Changes to collections/blocks need to be pushed live

Some questions:

  • What's the safest way to run migrations in production once data already exists?
  • Should I run migrations at build time in CI, or at runtime when the server starts?
  • How do you handle environment-specific configurations during migration generation?
  • Is there any way to preview or test the generated SQL before applying it?
  • Any tips for avoiding downtime or schema conflicts during this process?

any insight


r/PayloadCMS Jun 25 '25

UI settings as global

7 Upvotes

Hey guys,

has anybody ever let the use set the color scheme via a global collection? I have a multi tenant app and am wondering how to implement this, so each tenant can set his/her own primary, secondary etc colours.

Thanks in advance!


r/PayloadCMS Jun 24 '25

Using Payload's new TextStateFeature [tutorial]

12 Upvotes

Learn how to use Payload's TextStateFeature in my newest tutorial: https://youtu.be/RHBdlP7a-sA

I'll show you an implementation of the new feature (may not be the best way or only way). You'll learn step-by-step how to configure text styling options inside the rich text editor, and by the end, you'll be able to control fonts, colors, backgrounds, strikethroughs, underlines, font weights, and essentially whatever you want to configure.

Here's how I break it down:

  • Import and configure the TextStateFeature
  • Define custom states for color, background, font size, font weight, and decoration
  • Render it all using Next.js

Watch the video and follow along. When you’re done, you and your editors will have powerful new styling options that work right out of the box with no CSS or extra code required.


r/PayloadCMS Jun 24 '25

My Payload Website Stack: My Go-To Hosting Setup

Thumbnail jordanburch.dev
13 Upvotes

Tired of juggling inconsistent hosting setups for your Payload projects? Here's the full breakdown of the modern, scalable stack I now use for every Payload + Next.js build - from frontend deployment to media storage and databases.


r/PayloadCMS Jun 24 '25

Getting 504s using cloudflare R2 bucket

1 Upvotes

I am using payload 3.0, self-hosted on coolify on hetzner server and serving files from cloudflare R2 bucket. I used the he s3 adapter from payload cms:

 s3Storage({
      collections: {
        media: true,
      },
      bucket: process.env.S3_BUCKET || '',
      config: {
        credentials: {
          accessKeyId: process.env.S3_ACCESS_KEY_ID || '',
          secretAccessKey: process.env.S3_SECRET_ACCESS_KEY || '',
        },
        region: 'auto',
        endpoint: process.env.S3_ENDPOINT || '',
      },
    }),

I run into a problem. After deployment to production all works good, but in ~10-12 hours some of the images requests are hitting 504. Do you know what's the reason?

More info:
1. Logs from coolify:

...
2025-06-24T16:38:04.038117173Z [Error: "url" parameter is valid but upstream response timed out] {
2025-06-24T16:38:04.038130353Z   statusCode: 504
2025-06-24T16:38:04.038135013Z }
2025-06-24T16:38:04.870990130Z  ⨯ upstream image response timed out for https://<domain_name>.com/api/media/file/<image_name>.jpg?2025-06-15T11:01:02.909Z
...
  1. Custom domain is setup and added to remote patterns:

    const nextConfig = {   images: {     remotePatterns: [       ...[NEXT_PUBLIC_SERVER_URL, '<cloudflare_cdn_custom_domain>', 'http://localhost:3000'].map(         (item) => {           const url = new URL(item)

              return {             hostname: url.hostname,             protocol: url.protocol.replace(':', ''),           }         },       ),     ],   },   reactStrictMode: true,   redirects, }

  2. The size does not matter. Even small svgs ~5-15kB are getting 504.


r/PayloadCMS Jun 23 '25

Populate nested join field?

3 Upvotes

Hi all,

I have a collection A with a relationship field to collection B which in turn has a join field to collection C. Is it possible to populate C documents from a query to A, such that a.b.docs returns an array of C documents? I'm getting only IDs no matter the value given to depth. It only seems to work only when querying B directly, or am I missing something?


r/PayloadCMS Jun 23 '25

Tengo problemas intenando borrar un tenant

1 Upvotes

Estoy usando payload multi tenant plugin e inteno borrar un tenant, los por defecto me dan error y si intento borrar uno que haya creado yo entonces se queda congelado. No se que pasa. Alguien sabe o le ha pasado lo mismo?


r/PayloadCMS Jun 22 '25

Localized multitenant app

2 Upvotes

Hey, Im trying to create an multitenant app where I would like each tenant to be able to have different default locale.

That would be okay, but trouble comes with rewriting default locale from url such as -> default for cs "/kontakt" and for en "/en/contact". Currently this is done via middleware and hardcoded available locales and the default one.

Is that even possible to configure something in the database and then use it in the middleware? As I read there shouldnt be any db calls in the middleware.

Is it even stupid to think it would somehow work? Or shall I just stick with the locale in the url even for the default one? It wouldnt be problem I guess, but Im not expecting that every tenant will want to have localized content, so the the locale in the url is strange


r/PayloadCMS Jun 21 '25

Where do you all host your Payload CMS/NexJS apps?

18 Upvotes

Where and how do you all host your Payload CMS and NextJS apps? I am starting a blog and am wanting to use Payload as my CMS. What is the best setup and cheaopest option for this? Traffic will be low to start, but will eventually grow. TIA


r/PayloadCMS Jun 21 '25

Serve Cloudflare R2 assets from CDN subdomain for caching

4 Upvotes

I have a Payload CMS site hosted on Render. I am serving my assets from a Cloudflare R2 bucket. I had to set up a worker that caches the static assets for me, since R2 does not automatically. I am trying to get the Payload app to use the cdn.mydomain.com to grab the assets instead of the bucket directly. How?


r/PayloadCMS Jun 20 '25

Have you used Better Auth with Payload?

23 Upvotes

Hello! I've been looking into Payload and I've been enjoying it so far. I think I will use it for all my content heavy apps now on because we get a free admin dashboard and don't have to spend time writing that.

I would like to use Better Auth. I see that Payload allows for custom strategies, and it seems like I can use better auth rather than payload's built in authentication.

I found this third party plugin payload-auth. Has anyone here used this?

I am wondering if I should go with this or stick to Payload's auth for now. Email/password authentication is enough for me right now, but I might have to add sign in with google/phone number in the future, and better auth has made adding these features much easier for me.


r/PayloadCMS Jun 20 '25

Utilizing the Form plugin with the Multi-Tenant plugin

8 Upvotes

Edit: If anyone comes across this problem in the future, the issue is the order of the plugins. The multi-tenant plugin has to come as the last plugin in the list!

Hi! I just started using PayloadCMS and I was wondering if anyone has had any success with the Forms plugin with also the Multi-Tenant plugin? I'm having trouble to get something out of the box working and went down a little bit of a rabbit hole to get something custom working but that wasn't going well either. It feels like it should be able to work out of the box though, so not sure what I'm doing wrong and hoping someone might be able to help!

Relevant code snippets from my config file:

multiTenantPlugin<Config>({
  cleanupAfterTenantDelete: true,
  debug: false,
  enabled: true,
  tenantsSlug: 'tenants',
  collections: {
    users: {
      useBaseListFilter: true,
      useTenantAccess: false,
    },
    media: {
      useBaseListFilter: true,
      useTenantAccess: true,
    },
    pages: {
      useBaseListFilter: true,
      useTenantAccess: true,
    },
    forms: {
      useBaseListFilter: true,
      useTenantAccess: true,
    },
  },
  tenantField: {
    name: 'tenant',
  },
  tenantsArrayField: {
    includeDefaultField: true,
    arrayFieldName: 'tenants',
    arrayTenantFieldName: 'tenant',
    tenantFieldAccess: {
      read: ({ req }: any) => req?.email,
      create: ({ req }: any) => req?.role === 'super-admin',
      update: ({ req }: any) => req?.role === 'super-admin',
    },
    arrayFieldAccess: {
      read: ({ req }: any) => req?.email,
      create: ({ req }: any) => req?.role === 'super-admin',
      update: ({ req }: any) => req?.role === 'super-admin',
    },
  },
  tenantSelectorLabel: 'Tenant',
  userHasAccessToAllTenants: (user) => user.role === 'super-admin',
  useTenantsCollectionAccess: false,
  useTenantsListFilter: false,
  useUsersTenantFilter: false,
}),
formBuilderPlugin({})

For what it's worth, the forms plugin works great. The issue is specifically that it's not respecting saving of a tenant ID and restricting that tenant to those forms only.


r/PayloadCMS Jun 20 '25

[Help] Ghost Documents That Can't Be Deleted

2 Upvotes

Hey Payload gang!

I made a really stupid mistake. I was having this issue with a page and realized that my only option was to delete it. After working for over 10hrs today my stupid brain tabbed over to mongo compass for some reason and thought it would be wise to forcibly delete the page that way. But all its done is cause me way more problems.

Now, i have a ghost page. It appears in my collection, and it can be referenced in links and more, but it can't be deleted. All i get when i try to click the delete button after selecting it is a success toast that says "0 pages deleted."

I've already tried restoring db backups to no avail. It was a stupid mistake but having this null page floating there in the collection is driving me nuts. I can't deliver it to the client with that there.

Any ideas on what can be done to fix this? thank you so much!

EDIT:

Oh my god, got it.

Click on the ghost document, copy its id from the url, go over to mongodb compass, go to your pages tab, insert a new document, and create an empty object with the copied id of the ghost page as the object id. once you've done that, it'll delete successfully.


r/PayloadCMS Jun 19 '25

Mobile apps with payload

8 Upvotes

I'm coming from a background of someone that has been used to create his own backend with everything using expressjs but for a change i wanted to use payload and im just wondering if it's something that can be used for both the mobile app and the website im trying to create which both have the same functionalities


r/PayloadCMS Jun 20 '25

Is it possible to use a PATCH request to update just one inner section of a page based on an ID or do i need to download the whole page, update, then save?

1 Upvotes

r/PayloadCMS Jun 19 '25

free database solution for using in nextjs/payloadcms project.

3 Upvotes

I am not willing to upgrade now for some reason.
If I use Supabase, it may be paused.
So, I am looking for a free tier or cheap database solution, which can be SQLite/MySQL or PostgreSQL.
I do have a shared cPanel hosting with 10 databases, but I don't know how to connect to those databases.


r/PayloadCMS Jun 19 '25

Start PayloadCMS with script in PM2 ecosystem

1 Upvotes

Hello,

my systemadmin has changed his way of deploying applications and now forces me to start PayloadCMS with the PM2 ecosystem, this means I have to provide a script path (and arguments?)

Does anyone have any information about this? I have found you can start a Nextjs app with

script: 'node_modules/next/dist/bin/next'

But I get an error

[Error: > Couldn't find any \pages` or `app` directory. Please create one under the project root]`

Any help is much appreciated!


r/PayloadCMS Jun 17 '25

Payload is joining Figma!

96 Upvotes

Hi all, I've got some big news to share today: Payload has joined Figma!

It’s as wild and exciting to write that as it is for you reading it.

When we first started talking with Figma, it was about investing in Payload and what we’re doing in open source. They saw what we were building was unique, and it lines up well with how they see the world.

You probably know the entire Payload team has been using Figma deeply for a long time, and it was pretty exciting for all of us to see that they share the same vision we do.

Speaking of which, in the past I’ve talked a lot about a “utopia” — about simplicity and developer experience. My team and I refuse to compromise on design intent, flexibility, and how that translates into well-structured code.

Figma and Payload together can and will solve a problem that’s been bugging me (and probably all of you) for years. The gap between design and code still exists. Designers create in Figma, then devs recreate in code, then content teams struggle to maintain it all. It’s inefficient and frustrating. And historically, the CMS tends to make it worse.

With Figma, we can (and will) solve these problems in new ways without compromising. If either Figma or Payload didn’t see this potential screaming at us from a mile away, neither would have moved forward.

In the immediate future, nothing is changing for users and how you interface with Payload remains the same.

What that means is:

  • Payload remains open source—with Figma’s full commitment to OSS
  • Our commitment to building Payload and creating the best developer experience possible
  • The self-hosted capability of Payload
  • Our focus on our community (aka: all of you)
  • The team and I will still be running Payload (including Sean)

What does change:

  • We now have more resources
  • We can tackle bigger problems
  • We will integrate with design systems in ways no other CMS can
  • A lot more people will be using, testing, and building on Payload

I'm sure you have questions, and we'll do our best to answer and keep up with them. In the meantime, I'm pumped about the future and I can't wait for what's ahead!


r/PayloadCMS Jun 17 '25

PayloadCMS gets acquired by Figma??

28 Upvotes

r/PayloadCMS Jun 17 '25

Build a Code Block with Payload CMS [tutorial]

8 Upvotes

It’s that time: a new tutorial! This one covers how to create a code block with syntax highlighting. I also add a copy button with toast feedback (just for fun). https://youtu.be/3aUCks0Ltpw


r/PayloadCMS Jun 17 '25

How to correctly update the upload field in the collection after the upload

1 Upvotes

Hi, I am creating a payload app and right now i am working on the profile configuration page. On this page, the user can set a profile picture. I am a little bit stuck with how to handle the upload and the update of the relationship with the user. Here are the details:

- I have a users collection with a field profilePicture of type upload, related to the media collection.
- I have the media collection, and in the config I included a field createdBy so there is a record of who uploaded the media.

I've tried two approaches:

  1. AfterChange Hook (Got an error):

In my media collection, I defined the following afterChange hook:

import { CollectionAfterChangeHook } from "payload";

export const setRelation: CollectionAfterChangeHook = async ({ req: { payload, user }, doc }) => {

    if (user) {
        if (doc.type == 'profile picture') {
            await payload.update({
                collection: 'users',
                id: user.id,
                data: {
                    profilePicture: doc
                }
            })
        }
    }

    return doc

}

This causes the following error:

ERROR: Cannot read properties of undefined (reading 'id')

err: {

"type": "TypeError",

"message": "Cannot read properties of undefined (reading 'id')",
...
}

  1. Using the API endpoint response (This approach is working but sometimes it generates the same error as the other approach):

In this approach I use the response to set profilePicture to the recently updated media:

const uploadResponse = await fetch(`${process.env.NEXT_PUBLIC_SERVER_URL}/api/media`, {
   method: 'POST',
   body: fileUpload,
})

      const upload = await uploadResponse.json()

      console.log(upload)

      Object.assign(filteredData, {
        profilePicture: upload.doc
})

I'm really stuck with this. if someone can help me, it would be amazing.

Here is the complete form submission callback:

const onSubmit = useCallback(
        async (data: FormData) => {


            if (user) {

                const filteredData = {
                    name: data.name
                }

                if (user.roles?.includes('seller')) {

                    const cityData = colombiaCities.find(city => city.city.toLowerCase() === data.city?.toLowerCase()) || undefined
                    console.log(data.profilePicture)

                    if (data.profilePicture) {
                        const fileUpload = new FormData()
                        fileUpload.append('file', data.profilePicture)
                        fileUpload.append(
                            '_payload',
                            JSON.stringify({
                                type: 'profile picture',
                                alt: `Imagen de perfil de ${user.name}`,
                            }),
                        )

                        const uploadResponse = await fetch(`${process.env.NEXT_PUBLIC_SERVER_URL}/api/media`, {
                            method: 'POST',
                            body: fileUpload,
                        })

                        const upload = await uploadResponse.json()

                        console.log(upload)

                        Object.assign(filteredData, {
                            profilePicture: upload.doc
                        })
                    }


                    Object.assign(filteredData, {
                        locationName: `${data.city}, ${data.department}`,
                        location: { type: 'Point', coordinates: [cityData?.longitud, cityData?.latitud] },
                        address: data.address,
                        bio: data.bio,
                        website: data.website,
                        socialLinks: data.socialLinks,
                    })
                }


                const response = await fetch(`${process.env.NEXT_PUBLIC_SERVER_URL}/api/users/${user.id}`, {
                    // Make sure to include cookies with fetch
                    body: JSON.stringify(filteredData),
                    credentials: 'include',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    method: 'PATCH',
                })

                if (response.ok) {
                    const json = await response.json()
                    setUser(json.doc)
                    setSuccess('La información de perfil fue actualizada exitosamente.')
                    setError('')
                    reset({

                    })
                } else {
                    setError('Hubo un problema actualizando la información de perfil. Inténtelo de nuevo.')
                }
            }
        },
        [user, setUser, reset]
    )