DEV Community

Aaron K Saunders
Aaron K Saunders

Posted on

2

Display Images in your Payload CMS Admin Collection List with Custom Cell Component

Here’s how to write a cell data component in Payload CMS to get images to appear in your Collection List. Displaying Images on your Payload CMS Admin is as easy as setting the server’s URL.

This guide uses a custom component to fetch and render the image. Full source code can be found at: aaronksaunders/payload-custom-cell-image-component-1-2025

Setting Server URL
The first thing we need to do is make sure our payload.config.ts knows where to find our URL.

// payload.config.ts

export default buildConfig({
  serverURL: process.env.SERVER_URL || 'http://localhost:3000',
Enter fullscreen mode Exit fullscreen mode

Make sure that your server knows where to retrieve media from by putting this into your config, be that from local or from another host, this would be how it gets set.

If you dont set this, the url for the media will be incorrect and probably not render properly

User List Modifications

To make your User List modifications, the first step is to create a new avatar field with a relationship to the Media collection. This is defined within your Users.ts collection configuration:

// Users.ts
{
  name: 'avatar',
  type: 'relationship',
  relationTo: 'media',
  admin: {
    components: {
      Cell: 'src/collections/CustomImageCell',
    },
  },
},
Enter fullscreen mode Exit fullscreen mode

Important to note that with Payload 3, you now need to specify the full path to the custom cell component, you cannot just import the object like in version 2

Custom Component Creation (CustomImageCell.tsx)

// src/collections/CustomImageCell.tsx
import React from 'react'
import Image from 'next/image'
import { type DefaultServerCellComponentProps } from 'payload'

const MyComponent = async ({ cellData, payload }: DefaultServerCellComponentProps) => {

  // thanks to Jarrod for the following simplification, payload
  // is already available in the props so no need to load config
  // and get payload again

  const media = await payload.findByID({
    collection: 'media',
    id: cellData,
  })
  console.log(media)

  return (
    <div
      style={{
        position: 'relative',
        width: '80px',
        height: '80px',
      }}
    >
      <Image
        src={media.url!}
        alt={media.alt}
        fill
        style={{
          objectFit: 'contain',
        }}
      />
    </div>
  )
}
export default MyComponent
Enter fullscreen mode Exit fullscreen mode

The CustomImageCell component is a server component that asynchronously fetches the Media object using the payload object that is passed in as a component property. Note the use of Next.js's Image component for optimized image delivery.

The component receives the id of the media as a prop and utilizes it to retrieve all the image data.

Next JS Config Modification (next.config.js)

Lastly, because Next JS can generate an error about the specified URL, it would be useful to add to your remote Patterns.

In your next.config.js file, you'll need to configure the remotePatterns array to allow the Image component to load images from your Payload CMS instance.

// next.config.js
const nextConfig = {
  // ... other config
  images: {
    remotePatterns: [
      {
        protocol: 'http',
        hostname: 'localhost',
        port: '3000',
        pathname: '/media/**',
      },
    ],
  },
};

module.exports = nextConfig;
Enter fullscreen mode Exit fullscreen mode

If the localhost is throwing too many errors, can also modify the .env variable.

This configuration allows images to be loaded from localhost port 3000, where Payload CMS is running in development. Adapt the protocol, hostname, and pathname to match your specific setup. You may also be able to utilize the variable, depending on your specific version and setup.

Summary:

  • Fetching Media Data: The custom component fetches the media data by ID.
  • Rendering the Image: It then utilizes Next.js to render the image.

Links

SurveyJS custom survey software

Build Your Own Forms without Manual Coding

SurveyJS UI libraries let you build a JSON-based form management system that integrates with any backend, giving you full control over your data with no user limits. Includes support for custom question types, skip logic, an integrated CSS editor, PDF export, real-time analytics, and more.

Learn more

Top comments (3)

Collapse
 
dansasser profile image
Daniel T Sasser II

How long have you been working with PayloadCMS?

Collapse
 
aaronksaunders profile image
Aaron K Saunders

Since v2 when they went open source. We have deployed it to three clients, we are not a website, design agency though we use it as an application platform for mobile apps and websites. Leverage the integrated platform to help us build more efficiently.

Collapse
 
dansasser profile image
Daniel T Sasser II

Nice! I have been using it as a CMS to power our new platform we are building, that is similar to Shopify, while our custom CMS is under development. I had it all set up really nice before the update. I was able to migrate every easily except I've been having trouble with the custom logo stuff on the login page. The types are a little different there now. I think I almost got it figured out. Our custom CMS uses lexical just like payloadCMS.

nextjs tutorial video

Youtube Tutorial Series 📺

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series 👀

Watch the Youtube series