jeanbmar

payload s3 upload

by jeanbmar
Cloud storage
v1
^1.x.x
MIT

Overview

Summary generated from the README

Sends files uploaded through Payload upload collections to Amazon S3 instead of the server file system, including generated image sizes. It is registered as a plugin with an S3 client, and bucket, prefix and PutObject options are set on each collection's upload config. Targets Payload 1.x.

Features

  • Uploads files and resized image variants to Amazon S3
  • Per-collection bucket and prefix settings on the collection config
  • Dynamic prefixes via a function receiving the document
  • Pass any PutObjectCommandInput option such as ACL
  • Typed S3UploadCollectionConfig for collection definitions

Use cases

  • Move media uploads off the local disk to an S3 bucket
  • Store files from different collections in separate buckets or folders

From the author

Send Payload CMS uploads to Amazon S3

Installation

npm i payload-s3-upload

70

Stars

11

Forks

5

Open Issues

3 years ago

Last Updated

0

Weekly Downloads

v2.1.1

npm Version

21.1 KB

Unpacked Size

1

Dependencies

GitHub stars

Trends appear after 7 days of data. Daily snapshots have not started yet.

npm weekly downloads

Trends appear after 7 days of data. Daily snapshots have not started yet.

Each point is npm's rolling 7-day download count.

Health Score

36/100Fair

Composite score based on GitHub activity, stars, npm downloads, publish recency, dependency count, and package size.

Badge for your README

Payload Directory health badge
Markdown
[![Payload Directory](https://payloaddirectory.dev/badge/393192786-root.svg)](https://payloaddirectory.dev/plugins/393192786-root)
HTML
<a href="https://payloaddirectory.dev/plugins/393192786-root"><img src="https://payloaddirectory.dev/badge/393192786-root.svg" alt="Payload Directory"></a>
Updated Aug 9, 2023Created Aug 5, 2021Published May 16, 2023

README

Upload files to S3 in Payload CMS

This plugin sends uploaded files to Amazon S3 instead of writing them to the server file system.
Resized images are properly supported.

Why should I use this module?

Payload team supports an official cloud storage plugin, different from this one.

The main difference is that this plugin allows configuring collection logic on the collection itself.

Payload implementation requires to define collection-specific stuff from plugins inside the global payload configuration file, which is (imho) bad design.

Install

npm install payload-s3-upload --legacy-peer-deps

Payload requires legacy-peer-deps because of conflicts on React and GraphQL dependencies (see Payload docs).

Getting Started

Enable plugin in Payload CMS config

import { S3Client } from '@aws-sdk/client-s3';
import { buildConfig } from 'payload/config';
import s3Upload from 'payload-s3-upload';

export default buildConfig({
  // ...
  plugins: [
    s3Upload(new S3Client({
      region: process.env.AWS_REGION,
      credentials: {
        accessKeyId: process.env.AWS_KEY,
        secretAccessKey: process.env.AWS_SECRET,
      },
    })),
  ],
});

Configure your upload collections

import { S3UploadCollectionConfig } from 'payload-s3-upload';

const Media: S3UploadCollectionConfig = {
  slug: 'media',
  upload: {
    staticURL: '/assets',
    staticDir: 'assets',
    disableLocalStorage: true,
    s3: {
      bucket: 'my-bucket',
      prefix: 'images/xyz', // files will be stored in bucket folder images/xyz
      // prefix: ({ doc }) => `assets/${doc.type}`, // dynamic prefixes are possible too
      commandInput: {
        // optionally, use here any valid PutObjectCommandInput property
        // https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/putobjectcommandinput.html
        ACL: 'public-read',  
      },
    },
    adminThumbnail: ({ doc }) =>
      `https://my-bucket.s3.eu-west-3.amazonaws.com/images/xyz/${doc.filename}`,
  },
  // create a field to access uploaded files in s3 from payload api
  fields: [
    {
      name: 'url',
      type: 'text',
      access: {
        create: () => false,
      },
      admin: {
        disabled: true,
      },
      hooks: {
        afterRead: [
          ({ data: doc }) =>
            `https://my-bucket.s3.eu-west-3.amazonaws.com/images/${doc.type}/${doc.filename}`,
        ],
      },
    },
  ],
};

export default Media;

Recipe for handling different sizes

This plugin automatically uploads image variants in S3.

However, in order to retrieve correct URLs for the different sizes in the API, additional hooks should be implemented.

import { S3UploadCollectionConfig } from 'payload-s3-upload';

const Media: S3UploadCollectionConfig = {
  slug: 'media',
  upload: {
    // ...
    imageSizes: [
      {
        name: 'thumbnail',
        width: 400,
        height: 300,
        crop: 'center'
      },
      {
        name: 'card',
        width: 768,
        height: 1024,
        crop: 'center'
      },
      {
        name: 'tablet',
        width: 1024,
        height: null,
        crop: 'center'
      }
    ],
    adminThumbnail: 'thumbnail',
  },
  hooks: {
    afterRead: [
      ({ doc }) => {
        // add a url property on the main image
        doc.url = `${myBucketUrl}/${doc.filename}`

        // add a url property on each imageSize
        Object.keys(doc.sizes)
          .forEach(k => doc.sizes[k].url = `${myBucketUrl}/${doc.sizes[k].filename}`)
      }
    ]
  },
  fields: []
};

export default Media;

Working Example

Please refer to the test files!

Similar plugins