Бібліотека медіа в Payload CMS
Payload керує медіафайлами через спеціальну колекцію з типом upload. Файли можуть зберігатися локально або в хмарі (S3, Cloudflare R2, GCS) через офіційні плагіни адаптерів.
Базова колекція Media
// collections/Media.ts
import type { CollectionConfig } from 'payload/types'
const Media: CollectionConfig = {
slug: 'media',
upload: {
staticURL: '/media',
staticDir: 'public/media', // локальне зберігання
imageSizes: [
{ name: 'thumbnail', width: 400, height: 300, crop: 'center' },
{ name: 'card', width: 768, height: 512, crop: 'center' },
{ name: 'tablet', width: 1024, withoutEnlargement: true },
],
adminThumbnail: 'thumbnail',
mimeTypes: ['image/*', 'application/pdf'],
// максимальний розмір файлу (байти)
limits: { fileSize: 10 * 1024 * 1024 },
},
fields: [
{
name: 'alt',
type: 'text',
required: true,
},
{
name: 'caption',
type: 'text',
},
],
}
export default Media
S3-сховище через плагін
npm install @payloadcms/storage-s3
// payload.config.ts
import { s3Storage } from '@payloadcms/storage-s3'
export default buildConfig({
plugins: [
s3Storage({
collections: {
media: {
prefix: 'media',
generateFileURL: ({ filename, prefix }) =>
`${process.env.CDN_URL}/${prefix}/${filename}`,
},
},
bucket: process.env.S3_BUCKET!,
config: {
region: process.env.S3_REGION || 'eu-west-1',
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY!,
secretAccessKey: process.env.S3_SECRET_KEY!,
},
endpoint: process.env.S3_ENDPOINT, // для Cloudflare R2 або MinIO
},
}),
],
})
Для Cloudflare R2 встановіть endpoint = https://<account-id>.r2.cloudflarestorage.com, region = auto.
Cloudflare R2 + трансформація зображень
// collections/Media.ts — трансформація URL через Cloudflare Images
upload: {
imageSizes: [
{
name: 'thumbnail',
generateImageName: ({ height, sizeName, extension, width }) =>
`${sizeName}_${width}x${height}.${extension}`,
},
],
// Для R2 — не генерувати серверні зміни розміру, використовувати CF Image Resizing
disableLocalStorage: true,
}
Завантаження файлів через API
// Завантаження через REST API
const formData = new FormData()
formData.append('file', fileBlob, 'image.jpg')
formData.append('alt', 'Опис зображення')
const response = await fetch('/api/media', {
method: 'POST',
headers: { Authorization: `Bearer ${token}` },
body: formData,
})
const media = await response.json()
// media.url — URL файлу
// media.sizes.thumbnail.url — URL змінено розміру
Використання в інших колекціях
// Поле завантаження в колекції
{
name: 'featuredImage',
type: 'upload',
relationTo: 'media',
required: true,
}
// У Next.js компоненті
import Image from 'next/image'
const PostCard = ({ post }: { post: Post }) => {
const image = post.featuredImage
if (typeof image === 'string') return null // не заповнено
return (
<Image
src={image.sizes?.card?.url || image.url!}
alt={image.alt}
width={768}
height={512}
/>
)
}
Терміни
Налаштування бібліотеки медіа з S3/R2 сховищем, змінами розміру та інтеграцією колекцій — 0,5–1 день.







