Strapi Draft System Explained
Published: 2021-02-24 13:37:34

>This article is a guest post by  [**Precious Luke**](https://github.com/bigpreshy). He wrote this blog post through the [Write for the Community](https://strapi.io/write-for-the-community) program.

Strapi introduced the [Draft and Publish feature](/blog/announcing-a-new-draft-and-publish-feature) recently in version 3.2. This makes sense because it lets us manage content efficiently. So I am going to demonstrate how this works by building a mini-blog and also through API (REST and GraphQL). 
You will also learn a thing or two about Strapi file structure too.

[Github Url](https://github.com/bigpreshy/draftandpublish)

[Frontend](https://strapidraft.netlify.app/)

So I have installed and deployed Strapi on [Heroku](https://strapi.io/documentation/developer-docs/latest/deployment/heroku.html) and used MongoDB atlas as my database, (Please read [this](https://gist.github.com/bigpreshy/82d20a8228e17e3e0c6ced01ea4d48ec) and see how it's done as we are just trying to concentrate on the subject matter here) however, you can follow along with the ---quickstart flag like so:


    npx create-strapi-app my-project --quickstart

or

    yarn create strapi-app my-project --quickstart


So after the installation, the development server builds and starts automatically.
Your codebase will look like so:


![](https://paper-attachments.dropbox.com/s_F438CCB245ED8C8D20AF15CD9A236A703A4AD6FDD16A0996424F9C759F57BF64_1614160751234_file.jpeg)


Your Strapi project should be up and running at http://localhost:1337. 

We will create our first administrator and add some content to demonstrate how Draft and Publish Feature works


So I am going to create two collection types that have the following fields: **title(text)** and **body(richtext).**

I have decided to use **Article** and **Articleunpublished** here. You can use any display name you want but you should know that this will determine your API endpoints…

![](https://paper-attachments.dropbox.com/s_F438CCB245ED8C8D20AF15CD9A236A703A4AD6FDD16A0996424F9C759F57BF64_1614161836148_file.jpeg)


I have added some data.

## Note

By default, content created in Strapi stays in the draft until published, you can actually disallow the idea of Draft and Publish if you feel that there is no need for it. All you need to do is go to your codebase:

![](https://paper-attachments.dropbox.com/s_F438CCB245ED8C8D20AF15CD9A236A703A4AD6FDD16A0996424F9C759F57BF64_1612607986052_Screenshot+206.png)

and locate the api name you want to disallow its Draft and Publish,  **models/apiname.settings.json,**  then change the value of “draftAndPublish” from **true** to **false.** 
This way you would not have to click publish again as there won’t be any sort of Draft and Publish feature for that particular API.


**Alternatively**, you can disallow this feature when creating any content type by switching to **ADVANCED SETTINGS and toggle the Draft/publish system** OFF


![](https://paper-attachments.dropbox.com/s_F438CCB245ED8C8D20AF15CD9A236A703A4AD6FDD16A0996424F9C759F57BF64_1614167019027_5.jpg)


>Note that turning off the Draft and Publish feature while content is still in draft for a particular collection will delete the data from the database entirely. That is to say, if you have populated your created collection with data, all the data that is in the Draft state will be deleted when you disable Draft and Publish.

So back to it!

## Explaining Draft System Using REST and GraphQL

#### Getting Entries with a restful API using Insomnia

Strapi has already done so much work for you developers by giving us REST API capability out of the box…

Sending a GET request to the  http://localhost:1337/articles  fetch all the published content from the API

![](https://paper-attachments.dropbox.com/s_F438CCB245ED8C8D20AF15CD9A236A703A4AD6FDD16A0996424F9C759F57BF64_1614167068197_6.jpg)

#### Getting Entries with GraphQL 

By default, Strapi creates **REST endpoints** for each of the content types you create with it. Whereas, to use GraphQL, you will have to install GraphQL to use it. 

With the GraphQL plugin, you will be able to add a GraphQL endpoint to fetch and mutate your content.

You can download GraphQL in your admin by going to **Marketplace** or by running the following command in your terminal:


    npm run strapi install graphql

or 

    yarn strapi install graphql

![](https://paper-attachments.dropbox.com/s_F438CCB245ED8C8D20AF15CD9A236A703A4AD6FDD16A0996424F9C759F57BF64_1614167105505_7.jpg)


After we have installed GraphQL in our project, we can query specific published data in this endpoint http://localhost:1337/graphql. This will provide us graphiql.

Let’s us run this query in the Playground:


    query {
      articleunpublisheds {
        body
        title
      }
    }



![](https://paper-attachments.dropbox.com/s_F438CCB245ED8C8D20AF15CD9A236A703A4AD6FDD16A0996424F9C759F57BF64_1614167147616_8.jpg)


One of the cool benefits of GraphQL is the specification it brings to the table, how things and queries can be specified. This returns only the data we want it to return in *articleunpublisheds* endpoint. 



Running this in the Playground will return all the four entries in it because they were published. 

    query {
      articles {
        body
        title
      }
    }



#### Showing the Published Content

I am going to build a little frontend that will only display the contents that are published in the articles collection. This is the essence of the Draft system.


![](https://paper-attachments.dropbox.com/s_F438CCB245ED8C8D20AF15CD9A236A703A4AD6FDD16A0996424F9C759F57BF64_1614167204826_9.jpg)


Here is the code that fetches all available published articles from this endpoint. 

    http://localhost:1337/articles

This can be accessed here: https://strapidraft.netlify.app/

> The content might need some time to load, if you don't see the articles, try refreshing.


    //Published
    fetch('http://localhost:1337/articles').then((response) => {
            return response.json();
        })
        .then((data)=>{ 
                data.forEach(elem => {
                    const MasterDiv = document.getElementById('published');
                    console.log('foreach', elem.title);
                    const DivElement = document.createElement('div')
                    DivElement.classList.add('w3-quarter');
                    let img = document.createElement('ul', 'li'); 
                     let bigtitle = document.createElement('h3');
                     bigtitle.innerText = `${elem.title}`;
                     let bigbody = document.createElement('p');
                     bigbody.innerText = `${elem.body}`;
                     DivElement.append(img, bigtitle, bigbody);
                     MasterDiv.append(DivElement);
        
            }); 
        })
    
        
    

Here is the html file :


![](https://paper-attachments.dropbox.com/s_F438CCB245ED8C8D20AF15CD9A236A703A4AD6FDD16A0996424F9C759F57BF64_1614167251673_2.jpg)


You can find the code [here](https://github.com/bigpreshy/fantastic-doodle)!

#### Explaining the main.js

The code above fetches the API endpoints data from http://localhost:1337/articles  makes the result available in json format for easy consumption. 

I also did some DOM manipulations that create html tags with already styled classes.

**foreach** function is used here to define what happens in each instance of data from the endpoint:
First, it looks for an element that has an *id* of ***published***  in the **index.html** file and assigns it to **MasterDiv**.

    const MasterDiv = document.getElementById('published');


    

Secondly, it creates a div with a class of w3-quarter in it.




## Conclusion

This explains the technical things about the Draft and Publish feature which allows you to save content as a draft and publish it whenever you want. 
Once the content is published, it will be visible for frontend consumption.  This can however be reverted to unpublished(Draft state) when editing.

![](https://paper-attachments.dropbox.com/s_F438CCB245ED8C8D20AF15CD9A236A703A4AD6FDD16A0996424F9C759F57BF64_1614167285405_10.jpg)