Abbiamo recentemente migrato la gestione dei contenuti del sito Inmagik a Payload CMS. Per ottimizzare la gestione media dei contenuti dei sito, utilizziamo DigitalOcean Spaces, uno storage cloud compatibile con Amazon S3, che dispone anche di una CDN per ottimizzare il serving di questi contenuti e alleggerire il carico del webserver. Ecco come abbiamo fatto.
Upload con Payload CMS: configurazione base.
Payload CMS ha alcune funzionalità specifiche legate all'upload dei files, che gestisce attraverso l'individuazione di una o più collezioni dati preposte allo storage dei media, che possono essere referenziate da altre collezioni per implementare l'upload di files.
Di fatto questo modello di upload rende disponibile una "media gallery" a cui è possibile aggiungere immagini o altri tipi di media e riutilizzarli nei vari modelli dati del nostro sito.
La configurazione è molto semplice: è sufficiente creare una o più collections per gli upload, con una configurazione base come questa:
import type { CollectionConfig } from 'payload'
export const Media: CollectionConfig = {
slug: 'media',
upload: {
staticDir: 'media',
imageSizes: [
{
name: 'thumbnail',
width: 400,
height: 300,
position: 'centre',
},
],
adminThumbnail: 'thumbnail',
mimeTypes: ['image/*'],
},
fields: [
{
name: 'alt',
type: 'text',
},
],
access: {
read: () => true,
}
}
e utilizzare questa collection come campo di upload. Nel nostro caso, abbiamo aggiunto un campo upload alla nostra collection per gestire i post del nostro blog:
import type { CollectionConfig } from 'payload'
export const Blog: CollectionConfig = {
slug: 'blog',
admin: {
useAsTitle: 'slug',
},
fields: [
{
name: 'slug',
type: 'text',
required: true,
unique: true,
},
{
name: 'title',
type: 'text',
required: true,
localized: true,
},
// more fields here....
{
name: 'article',
type: 'code',
localized: true,
admin: {
language: 'markdown',
}
},
{
name: 'image',
type: 'upload',
relationTo: 'media',
required: false,
},
],
}
Nel nostro caso la collezione media
è referenziata dalla collezione blog
dal campo image
di tipo upload.
La collezione di upload così configurata è però basata su filesystem: i files aggiunti saranno salvati sul disco del server, nella posizione specificata nella configurazione della collection media
.
Si noti che la configurazione permette l'accesso in lettura tramite la specifica della dell'oggetto access
, che in questo caso definisce che la lettura è sempre possibile.
Storage adapters di Payload CMS
Per ottimizzare la gestione dei media e astrarre il concetto di storage, Payload mette a disposizione gli Storage Adapters. Questi adapters consentono di archiviare i file in diverse posizioni, come Amazon S3, Vercel Blob Storage, Google Cloud Storage e altri.
Configurare storage S3 per DigitalOcean Spaces
Per il nostro sito utilizzeremo l'adapter S3 Storage e lo configureremo per utilizzare DigitalOcean Spaces, un servizio di file storage compatibile con Amazon S3.
E' necessario quindi installare lo storage:
npm i @payloadcms/storage-s3
e configurare Payload per utilizzare questa libreria. La configurazione è nel file payload.config.ts
. Riportiamo solo le parti della configurazione che riguardano lo storage adapter.
import path from 'path'
import { buildConfig } from 'payload'
import { s3Storage } from '@payloadcms/storage-s3'
import { Media } from './collections/Media'
import { Blog } from './collections/Blog'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
export default buildConfig({
// more configuration keys here ...
// Define and configure your collections in this array
collections: [Media, Blog],
typescript: {
outputFile: path.resolve(dirname, 'payload-types.ts'),
},
plugins: [
s3Storage({
collections: {
media: {
generateFileURL: ({ filename }) => {
return `https://${process.env.S3_BUCKET}.${process.env.S3_REGION}.cdn.digitaloceanspaces.com/${filename}`
},
},
},
acl: 'public-read',
bucket: process.env.S3_BUCKET || '',
config: {
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY_ID || '',
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY || '',
},
// ... Other S3 configuration
region: process.env.S3_REGION || 'ams3',
endpoint: process.env.S3_ENDPOINT || undefined,
},
}),
// more plugins configured here
],
})
Questa configurazione di Payload abilita il plugin S3 storage per la collezione media
definita sopra.
Le parti importanti di questa configurazione sono:
- la definizione di una funzione per generare l'url di un file, che costruisce l'url sulla base della nostra CDN. (In questo caso stiamo gestendo solo l'url per l'immagine "base" e non per le varie dimensioni configurate nella collection di upload).
- L'
acl
policy che carica i files inpublic-read
ovvero rendendoli accessibili da chiunque una volta noto l'url. Ovviamente per il funzionamento le costantiS3_BUCKET, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_ENDPOINT, S3_REGION
devono essere definite (tipicamente in un file.env
).