Scheduled publication
This guide will help you set a publication date for an “Article” content-type, and at this date, toggle the draft
state to published
.
Prerequisites:
- You have used the Content-type Builder to create an Article collection type.
- You have enabled the Draft & publish feature on the Article collection type.
Set up the admin panel and prepare the content
By default, when using the Draft & Publish feature, entries have a publishedAt
field whose value is null
as long as the entry is in the draft state.
We will add another field, named publish_at
, to the “Article” content-type, to be able to define the date and time at which the article should be published. To achieve this:
- Click on the Content-type Builder link in the left menu.
- Select the “Article” collection type.
- Add another field to the “Article” collection type: choose the
date
type, name the fieldpublish_at
and choose thedatetime
type.
Then, from the Content Manager, create some new entries for the “Article” content-type with different publish_at
values and Draft & Publish states to be able to see the publication happen.
Make sure to create some entries with a draft state and a publish_at
that is before the current date.
The goal of the CRON task we’ll create next will be to check every minute if there are draft articles that have a publish_at
field value lower than the current date.
Create a CRON task
To execute a function every minute, we will use a CRON task.
To run a CRON task on the Strapi server, you need to:
- enable CRON tasks in the
./config/server.js
file by settingcron.enabled
totrue
(see documentation) - declare the CRON tasks. In our example, we will declare it within a dedicated file, but you could also declare it directly within the
cron.tasks
parameter of the./config/server.js
file.
Important
Please note that Strapi’s built-in CRON feature will not work if you plan to usepm2
or node-based clustering. You will need to execute these CRON tasks outside of Strapi.
The publishing logic will fetch all draft
entries from the “Article” content-type with a publish_at
value that is before the current date, then update the value of the published_at
of all these articles:
// path: ./config/cron-tasks.js
module.exports = {
/**
* Scheduled publication workflow.
* Checks every minute if there are draft articles to publish.
*/
'*/1 * * * *': async () => {
// fetch articles to publish;
const draftArticleToPublish = await strapi.entityService.findMany('api::article.article', {
publicationState: 'preview', // preview returns both draft and published entries
filters: {
publishedAt: {
$null: true, // so we add another condition here to filter entries that have not been published
},
publish_at: {
$lt: new Date() // and we keep only articles with a 'publish_at' datetime value that is lower than the current datetime
}
}
});
// update the publish_at of articles previously fetched
await Promise.all(draftArticleToPublish.map(article => {
return strapi.entityService.update('api::article.article', article.id, {
data: {
publishedAt: new Date(),
}
});
}))
},
};
And tada!