Skip to content

Repository files navigation

payload-plugin-scheduler

Plugin that adds an imperative field-based scheduling flow on top of Payload's native functionality, with at-a-glance schedule status in the admin UI.

Starting in v3, Payload has a built-in workflow for scheduling posts via the job queue and "Schedule Publish" drawer. This plugin adds a configurable Date field to opted-in collections and globals that, when set to a future date, automatically queues a schedulePublish job in the background with waitUntil set to that date. This results in a more ergonomic workflow for editors where they can view the schedule status at a glance in the document editor, and sort/filter by publish time in the list view.

This plugin was originally written for Payload v2, and included a background scheduler that's since been superseded by v3's native queue. For Payload v2, use version <=0.1.3.

ci status

UI Demo

Publish date field

List view

Requirements

  • Payload >= 3.90.0

Installation

npm add payload-plugin-scheduler

Usage

After configuring the plugin, ensure that you've regenerated payload's import map, otherwise the custom components won't display.

// payload.config.ts

import { buildConfig } from 'payload'
import { ScheduledPostPlugin } from 'payload-plugin-scheduler'

import Pages from './collections/Pages'
import Posts from './collections/Posts'
import Home from './globals/Home'

export default buildConfig({
  collections: [Pages, Posts, Users],
  globals: [Home],
  plugins: [
    ScheduledPostPlugin({
      collections: ['pages', 'posts'],
      globals: ['home'],
      interval: 10,
    }),
  ],
})

Running Jobs

This plugin creates Payload Jobs; it does not run the job worker for you. Your host app is responsible for running Payload's Jobs Queue.

See Payload's docs for current deployment guidance:

Options

Enabled collections and globals must support drafts. The plugin merges the required scheduled-publish draft config into versions.drafts.schedulePublish and preserves existing version/draft settings.

collections?: string[]

ScheduledPostPlugin({
  collections: ['pages', 'posts'],
})

globals?: string[]

ScheduledPostPlugin({
  globals: ['home'],
})

interval?: number

Time interval, in minutes, passed to the Date field's time picker and Payload's scheduled-publish draft config. Defaults to 5.

ScheduledPostPlugin({
  collections: ['posts'],
  interval: 15,
})

Your job queue cron interval should match this value, eg autoRun: [{ cron: '*/5 * * * *' }].

executionAccess?: 'user' | 'override'

Controls whose access permissions Payload uses when the scheduled publish job executes. Defaults to user.

  • user stores the authenticated scheduling user's ID on the job. Payload re-checks that user's current permissions at execution time. Scheduling without an authenticated user throws an error.
  • override omits the user from the job, causing Payload to execute it with access overridden.
ScheduledPostPlugin({
  collections: ['posts'],
  executionAccess: 'override',
})

publishDate?: object

Configure the generated publish-date field.

ScheduledPostPlugin({
  collections: ['posts'],
  // these are the default values
  publishDate: {
    name: 'publish_date',
    label: 'Publish Date',
    index: true,
    admin: {
      position: 'sidebar',
    },
  },
})

All properties are configurable except type, timezone, admin.date.pickerAppearance, admin.date.timeIntervals, admin.components.afterInput, and admin.components.Cell.

Manual Field Placement

By default, the plugin injects the publish-date field into every opted-in collection and global. If you need to place the field manually, use the exported publishDate() helper.

import type { CollectionConfig } from 'payload'
import { publishDate } from 'payload-plugin-scheduler'

export const Posts: CollectionConfig = {
  slug: 'posts',
  versions: {
    drafts: true,
  },
  fields: [
    {
      type: 'tabs',
      tabs: [
        {
          label: 'Content',
          fields: [
            {
              name: 'title',
              type: 'text',
            },
          ],
        },
        {
          label: 'Publishing',
          fields: [publishDate()],
        },
      ],
    },
  ],
}

Manual placement is only valid inside collections or globals that are opted in through ScheduledPostPlugin({ collections, globals }).

You can also pass arguments to publishDate to override the global publishDate options, eg to override the admin display properties on a one-off basis. Overrides are merged with the top-level publishDate config, with name being the only field that's only configurable at the global level.

publishDate({
  admin: {
    width: '50%',
    description: 'Custom description for this collection only'
  }
})

SafeRelationship

A drop-in replacement for Payload's relationship field, this is a helper field that throws an error if a user attempts to publish a document with relationships to unpublished documents.

import type { Field } from 'payload'
import { SafeRelationship } from 'payload-plugin-scheduler'

export const featuredContent: Field = SafeRelationship({
  name: 'featured_content',
  relationTo: ['posts', 'pages'],
  hasMany: true,
})

Debugging

Set DEBUG=payload-plugin-scheduler in your runtime env to enable debug logging.

Contributing

After cloning the repo and installing dependencies, run pnpm exec simple-git-hooks to setup automatic pre-commit linting.

Migration From v2

The v3 plugin no longer creates or writes to a plugin-owned scheduled_posts collection, and it no longer uses node-schedule. Scheduled publishes are represented as native Payload schedulePublish jobs in Payload's jobs collection.

To upgrade:

  • Remove any application code that reads from or customizes scheduled_posts.
  • Configure and run Payload Jobs in the host app. Dedicated servers and serverless deployments need different worker/cron strategies.
  • If you use Payload admin.timezones, verify the resulting <fieldName>_tz values in your own scheduling flow.
  • Generate and run a new database migration.
  • Rebuild payload's import map.

About

PayloadCMS plugin for automatic scheduled posts

Topics

Resources

Stars

32 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages