Skip to content

Instantly share code, notes, and snippets.

Last active March 30, 2023 12:18
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
@payloadcms/plugin-cloud-storage GCS adapter with local filesystem

The @payloadcms/plugin-cloud-storage allows you to upload files from Payload collections to a Google Cloud Storage bucket.

It relies on Node APIs that are not available in the browser.

The payload.config.ts is used by both the server of Payload and the frontend for the webpack build.

The GCS adapter for this plugin relies on the @google-cloud/storage which calls the Node APIs for processing and uploading files.

When you add this plugin to your payload.config.ts, and a collection uses a gcpAdapter, it will automatically extend your webpack config with the following (see:

'@google-cloud/storage': path.resolve(__dirname, './mock.js')

Which mocks the dependency using the Node APIs for webpack, allowing the frontend to be built and not throw any errors.

In my project, I want to allow both:

  1. Local filesystem uploads when GCS_CREDENTIALS nor GCS_BUCKET are set
  2. Cloud uploads when GCS_CREDENTIALS and GCS_BUCKET are set

My first attempt was something similar to this:

  collections: {
    'heroImages': {
      adapter: !!GCS_CREDENTIALS && !!GCS_BUCKET && myGcsAdapter,
      disableLocalStorage: !!GCS_CREDENTIALS && !!GCS_BUCKET,

However, since the adapter is not set, the plugin doesn't alias the dependency that uses the Node APIs, BUT they are still imported in the payload.config.ts file. This causes webpack to show many errors related to Node APIs that it says should be polyfilled or mocked.

The best workaround I have found is to define the plugin as noParse when you want to use the local filesystem. This stops webpack from parsing the plugin dependency and therefore the @google-cloud/storage.

In the attached payload.config.ts on a fresh install, this can be demonstrated by commenting out the custom webpack config and running npm run build which will error. Adding the custom webpack config and running npm run build will succeed.

import { buildConfig } from 'payload/config';
import { gcsAdapter } from '@payloadcms/plugin-cloud-storage/gcs';
import { cloudStorage } from '@payloadcms/plugin-cloud-storage';
import { HeroImageCollection } from './collections/HeroImageCollection';
const USE_LOCAL_STORAGE = !process.env.GCS_CREDENTIALS || !process.env.GCS_BUCKET
const myGcsAdapter = gcsAdapter({
options: {
credentials: JSON.parse(process.env.GCS_CREDENTIALS || "{}")
bucket: process.env.GCS_BUCKET || "",
const config = buildConfig({
admin: {
webpack: (config) => ({
module: {
noParse: /@payloadcms\/plugin-cloud-storage/,
collections: [
plugins: [
collections: {
'heroImages': {
adapter: !USE_LOCAL_STORAGE && myGcsAdapter,
disableLocalStorage: !USE_LOCAL_STORAGE,
(config: any) => {
return config;
export default config;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment