From 6bc4e6e8df14a5b645cfcee209f0e7e2a7638e09 Mon Sep 17 00:00:00 2001 From: Benno Tielen Date: Tue, 10 Mar 2026 08:59:38 +0100 Subject: [PATCH] feat: conditional gcs setup --- .env.example | 5 +++-- README.md | 9 +++++++++ src/payload-types.ts | 4 ---- src/payload.config.ts | 17 ++++++++++------- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/.env.example b/.env.example index dd7feee..8f21cb2 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,5 @@ DATABASE_URI=mongodb://127.0.0.1/dreikoenige PAYLOAD_SECRET=YOUR_SECRET_HERE -GOOGLE_BUCKET=google_storage_bucket -RESEND_API_KEY=some_api_key \ No newline at end of file +GOOGLE_BUCKET=google_storage_bucket #can be omitted +RESEND_API_KEY=some_api_key +PUBLIC_URL=http://localhost:3000 \ No newline at end of file diff --git a/README.md b/README.md index ffc2f93..324e41f 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,15 @@ Create and run a container, then set your `DATABASE_URI` to the Postgres URL. En Alternatively, you can enable the Postgres service in `docker-compose.yml` (currently commented out) and use that as your local DB. +## Google Cloud Storage + +Media and document uploads use `@payloadcms/storage-gcs`. The plugin is always registered but conditionally enabled via the `GOOGLE_BUCKET` environment variable: + +- **`GOOGLE_BUCKET` set** — files are uploaded to GCS and served from `https://storage.googleapis.com//`. +- **`GOOGLE_BUCKET` unset** — the plugin is disabled and Payload falls back to local file storage. The `alwaysInsertFields` flag keeps the schema identical in both cases, so `payload-types.ts` and `importMap.js` stay stable across environments. + +No additional configuration is needed for local development — simply omit `GOOGLE_BUCKET` from your `.env`. + ## Migrations (Payload) Create a new migration: diff --git a/src/payload-types.ts b/src/payload-types.ts index d7f7018..12918ba 100644 --- a/src/payload-types.ts +++ b/src/payload-types.ts @@ -259,7 +259,6 @@ export interface Church { */ export interface Document { id: string; - prefix?: string | null; updatedAt: string; createdAt: string; url?: string | null; @@ -285,7 +284,6 @@ export interface Media { publicWithoutName: boolean; consent: boolean; }; - prefix?: string | null; updatedAt: string; createdAt: string; url?: string | null; @@ -1654,7 +1652,6 @@ export interface MagazineSelect { * via the `definition` "documents_select". */ export interface DocumentsSelect { - prefix?: T; updatedAt?: T; createdAt?: T; url?: T; @@ -1681,7 +1678,6 @@ export interface MediaSelect { publicWithoutName?: T; consent?: T; }; - prefix?: T; updatedAt?: T; createdAt?: T; url?: T; diff --git a/src/payload.config.ts b/src/payload.config.ts index acf73e8..abaaf9c 100644 --- a/src/payload.config.ts +++ b/src/payload.config.ts @@ -10,7 +10,7 @@ import { AlignFeature, UnorderedListFeature, LinkFeature, - HTMLConverterFeature, FixedToolbarFeature, + FixedToolbarFeature, } from '@payloadcms/richtext-lexical' import path from 'path' import { buildConfig } from 'payload' @@ -141,22 +141,25 @@ export default buildConfig({ sharp, plugins: [ gcsStorage({ - + enabled: !!process.env.GOOGLE_BUCKET, + alwaysInsertFields: true, collections: { media: { disablePayloadAccessControl: true, prefix: 'media/', - generateFileURL: args => `https://storage.googleapis.com/${process.env.GOOGLE_BUCKET}/media/${args.filename}` + generateFileURL: (args) => + `https://storage.googleapis.com/${process.env.GOOGLE_BUCKET}/media/${args.filename}`, }, documents: { disablePayloadAccessControl: true, prefix: 'documents/', - generateFileURL: args => `https://storage.googleapis.com/${process.env.GOOGLE_BUCKET}/documents/${args.filename}` + generateFileURL: (args) => + `https://storage.googleapis.com/${process.env.GOOGLE_BUCKET}/documents/${args.filename}`, }, }, - bucket: process.env.GOOGLE_BUCKET || "", + bucket: process.env.GOOGLE_BUCKET || '', options: {}, - acl: undefined - }) + acl: undefined, + }), ], })