Skip to content

Latest commit

 

History

36 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Payloadflare poster

Payloadflare is a starter for building content-managed websites with Payload CMS and Next.js, designed to be hosted on Cloudflare Workers.

It is derived from Payload's official Cloudflare D1 template.

Important: This starter currently exceeds the Cloudflare Workers Free plan's script-size limit, so deployment requires a paid Workers plan.

It includes authenticated admin users, public media uploads, a form builder, and a blank frontend. Data is stored in D1 and media in R2.

Run locally

Requirements: Node.js 24.15.0 or later, pnpm, and a Cloudflare account.

pnpm install
pnpm wrangler login

Create a .env file with:

# Generate a secret with `openssl rand -hex 32`.
PAYLOAD_SECRET=replace-with-a-random-secret
NEXT_PUBLIC_SERVER_URL=http://localhost:3000

Start the app:

pnpm dev
  • Website: http://localhost:3000
  • Payload admin: http://localhost:3000/admin

Keep your project up to date

To bring template improvements into a project created from this repository, add this repository as an upstream remote once:

git remote add upstream https://github.com/larussverris/payloadflare.git

Then fetch and merge template updates when needed:

git fetch upstream
git merge upstream/main

Resolve any merge conflicts, then run the relevant checks before deploying.

Deploy to Cloudflare

Replace the placeholder names and IDs in wrangler.jsonc with your Worker, D1, and R2 resources.

The app uses:

  • D1 for Payload data
  • R2 for Payload media uploads
  • NEXT_INC_CACHE_R2_BUCKET for the Next.js incremental cache
  • NEXT_TAG_CACHE_D1 for cache-tag invalidation
  • NEXT_CACHE_DO_QUEUE to coordinate ISR revalidation
  • WORKER_SELF_REFERENCE as the Worker's self-service binding
  • EMAIL to send transactional email through Cloudflare Email

Configure transactional email

Set defaultFromAddress and defaultFromName in the email adapter configuration in src/payload.config.ts. These values are configured in code, not through environment variables. Keep defaultFromAddress in sync with allowed_sender_addresses on the EMAIL binding in wrangler.jsonc. The sender address must use a domain onboarded to Cloudflare Email. Onboard the domain before sending mail:

pnpm wrangler email sending enable example.com

The @payloadflare/email-cloudflare workspace package is configured in src/payload.config.ts, so auth emails and payload.sendEmail(...) use the EMAIL binding.

Enable D1 read replication

The first-primary strategy is enabled in src/payload.config.ts, but replicas must also be enabled on the database itself:

  1. Open the D1 database in the Cloudflare dashboard.
  2. Go to Settings.
  3. Enable Read Replication.

Configure the media domain and cache

Connect the media R2 bucket to a custom domain such as assets.yoursite.com, then set MEDIA_ORIGIN to that URL in the Cloudflare Worker environment. The app fails fast in production if it is missing.

Cloudflare's default Browser Cache TTL is four hours. Under Caching → Cache Rules, create a rule named R2 media - 30 day cache that keeps uploaded images and videos in both Cloudflare's edge cache and visitors' browser caches for longer.

Match the media hostname and image or video extensions:

(http.host eq "assets.yoursite.com" and http.request.uri.path.extension in {"avif" "gif" "jpg" "jpeg" "png" "svg" "webp" "mp4" "webm"})

Use these settings:

  • Cache eligibility: Eligible for cache
  • Edge TTL: Ignore cache-control header and use 30 days
  • Browser TTL: Override origin and use 1 hour

A Cloudflare cache purge cannot remove files already stored in visitors' browsers. When replacing a media file, use a new or versioned filename so its URL changes.

Before deploying schema changes, create a Payload migration:

pnpm payload migrate:create

Deploy the database migration and application together:

pnpm deploy

Optimizations

  • Metadata caching keeps robots.txt and llms.txt on the max cache profile and sitemap.xml on the hours profile.
  • Persistent Next.js cache stores SSG, ISR, and data-cache entries in R2.
  • Regional cache keeps frequently read cache entries close to the Worker for up to one minute.
  • D1 read replicas use Payload's first-primary strategy for consistent reads with lower latency after the initial primary query.
  • On-demand invalidation is supported through D1-backed Next.js cache tags when application code revalidates tagged content.
  • Deduplicated revalidation uses a Durable Object queue to avoid repeated ISR work.
  • Cloudflare image transformations resize images at /cdn-cgi/image, negotiate the output format automatically, and default to quality 85.
  • Direct media delivery serves production uploads from the configured media hostname instead of proxying them through Payload.
  • Static asset caching keeps Next.js's hashed /_next/static/* files immutable for one year and manually managed /static/* files cached for 30 days.
  • React Compiler is enabled for automatic React rendering optimizations.
  • Worker-aware bundling keeps jose and pg-cloudflare external for the workerd runtime.
  • Production logging writes structured JSON through console, which integrates with Cloudflare Workers logs.

Static files

Put manually managed assets in public/static/ (create the directory when needed):

public/static/logo.svg  ->  /static/logo.svg

Everything under /static/* is served with:

Cache-Control: public,max-age=2592000

These files are cached by browsers for 30 days. Versioned filenames such as logo-v2.svg or logo.abcd1234.svg are still useful when an update must appear immediately.

Other files placed directly in public/ use Cloudflare's normal static-asset caching unless another rule is added to public/_headers.

Uploads are limited to 6 MiB. Payload's Sharp-based crop and focal-point tools are disabled because Sharp is not supported in the Workers runtime.

About

A starter for building content-managed websites on Cloudflare Workers with Payload CMS and Next.js.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages