Crash Courses · PhD
Media & Uploads
Configure Payload media uploads with transformations and storage adapters.
10 min read+200 XP on completionCert: Payload CMS Crash Course
Tap any word in the text below to start reading from there.
Media & Uploads
Payload handles media uploads, image optimization, and multiple size generation automatically.
Media Collection
// collections/Media.ts
import type { CollectionConfig } from 'payload'
export const Media: CollectionConfig = {
slug: 'media',
upload: {
staticDir: 'public/media',
staticURL: '/media',
imageSizes: [
{ name: 'thumbnail', width: 400, height: 300, crop: 'center' },
{ name: 'card', width: 800, height: 500 },
{ name: 'hero', width: 1920, height: 1080 },
],
adminThumbnail: 'thumbnail',
mimeTypes: ['image/*', 'video/*'],
},
fields: [
{
name: 'alt',
type: 'text',
required: true,
},
{
name: 'caption',
type: 'text',
},
],
}S3 Storage Adapter (Vercel)
// payload.config.ts
import { s3Storage } from '@payloadcms/storage-s3'
export default buildConfig({
plugins: [
s3Storage({
collections: { media: true },
bucket: process.env.S3_BUCKET!,
config: {
region: process.env.S3_REGION!,
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY!,
secretAccessKey: process.env.S3_SECRET_KEY!,
},
},
}),
],
})Using Media in Next.js
import Image from 'next/image'
import type { Media } from '@/payload-types'
function MediaImage({ media, size = 'card' }: { media: Media; size?: string }) {
const url = media.sizes?.[size]?.url ?? media.url!
const width = media.sizes?.[size]?.width ?? media.width!
const height = media.sizes?.[size]?.height ?? media.height!
return (
<Image
src={url}
alt={media.alt}
width={width}
height={height}
className="w-full h-auto rounded-lg"
/>
)
}Reading progress
0% read
In this module
Upload collection
Image sizes
Storage adapter
Sharp
0%