✨ Strapi MCP is now Generally Available - let your agents manage your Strapi content ✨

How tos4 min read

How to create a Strapi v4 plugin
: Add a content-type to a plugin 3/6

May 23, 2022Updated on May 22, 2026

This article is a continuation of the following content: File structure part 2/6

The idea of the todo plugin is to have a list of tasks for every entry that you'll create in your project. This can be very useful for content-manager who wants to keep a clear vision of what needs to be done for a unique entry.

Todo is a simple list of tasks that needs to be saved in your application. Also, each task will be related to an existing entry but will see this later in this guide.

You can create a new collection-type using the generate CLI command or by directly creating/updating the necessary files in your code editor. Here, we'll do both:

# yarn
yarn strapi generate content-type

# npm
npm run strapi generate content-type
$ strapi generate content-type
? Content type display name: Task
? Content type singular name: task
? Content type plural name: tasks
? Please choose the model type: Collection Type
? Use draft and publish? No
? Do you want to add attributes? Yes
? Name of attribute: name
? What type of attribute: string
? Do you want to add another attribute? Yes
? Name of attribute: isDone
? What type of attribute: boolean
? Do you want to add another attribute? No
? Where do you want to add this model? Add model to an existing plugin
? Which plugin is this for? todo
? Bootstrap API related files? No

Content-type schema

The most important thing here is the ./src/plugins/todo/server/content-types/task/schema.json. This is the schema of your plugin collection-type. We are going to customize it by opening it in a code editor:

// ./src/plugins/todo/server/content-types/task/schema.json
{
  "kind": "collectionType",
  "collectionName": "tasks",
  "info": {
    "singularName": "task",
    "pluralName": "tasks",
    "displayName": "Task"
  },
  "options": {
    "draftAndPublish": false,
    "comment": ""
  },
  "attributes": {
    "name": {
      "type": "string"
    },
    "isDone": {
      "type": "boolean"
    }
  }
}

To become the following:

// ./src/plugins/todo/server/content-types/task/schema.json
{
  "kind": "collectionType",
  "collectionName": "tasks",
  "info": {
    "singularName": "task",
    "pluralName": "tasks",
    "displayName": "Task"
  },
  "options": {
    "draftAndPublish": false,
    "comment": ""
  },
  "attributes": {
    "name": {
      "type": "string",
      "required": true,
      "maxLength": 40
    },
    "isDone": {
      "type": "boolean",
      "default": false
    }
  }
}

As you can see, we are making the name field required and it can only contain less than 40 characters. Also, the isDone field is now false by default.

However, something is missing for Strapi to use this new collection-type. You need to make some manual updates.

Caution: These manual updates are necessary because of a bug in the generate CLI command. This will not be necessary for the future. The bug is that the schema created by Strapi is not automatically exported as it should be.

  • Create a ./src/plugins/todo/server/content-types/task/index.js file that will export the schema generated by Strapi:
// ./src/plugins/todo/server/content-types/task/index.js
'use strict';

const schema = require('./schema');

module.exports = {
  schema,
};
  • Update the ./src/plugins/todo/server/content-types/index.js file by exporting the content-type you just created:
// ./src/plugins/todo/server/content-types/index.js
'use strict';

const task = require('./task');

module.exports = {
  task,
};

You should now be able to see your new collection-type in the Content-Type Builder and Content Manager of your project.

Tipi: Don't forget, to build your admin to see your changes or follow this guide while having your server running with the --watch-admin option.

You can verify the integrity of your collection-type by running your server and eval commands in your application in real-time using the strapi console command.

# yarn
yarn strapi console

#npm
npm run strapi console
  • Then type the following command:
strapi.contentType('plugin::todo.task')

You should see this:

{
  "kind": "collectionType",
  "collectionName": "tasks",
  "info": { "singularName": "task", "pluralName": "tasks", "displayName": "Task" },
  "options": { "draftAndPublish": false, "comment": "" },
  "attributes": {
    "name": { "type": "string", "required": true, "maxLength": 40 },
    "isDone": { "type": "boolean", "default": false },
    "createdAt": { "type": "datetime" },
    "updatedAt": { "type": "datetime" },
    "createdBy": {
      "type": "relation",
      "relation": "oneToOne",
      "target": "admin::user",
      "configurable": false,
      "writable": false,
      "visible": false,
      "useJoinTable": false,
      "private": true
    },
    "updatedBy": {
      "type": "relation",
      "relation": "oneToOne",
      "target": "admin::user",
      "configurable": false,
      "writable": false,
      "visible": false,
      "useJoinTable": false,
      "private": true
    }
  },
  "__schema__": {
    "collectionName": "tasks",
    "info": { "singularName": "task", "pluralName": "tasks", "displayName": "Task" },
    "options": { "draftAndPublish": false, "comment": "" },
    "attributes": { "name": [Object], "isDone": [Object] },
    "kind": "collectionType"
  },
  "modelType": "contentType",
  "modelName": "task",
  "connection": "default",
  "uid": "plugin::todo.task",
  "plugin": "todo",
  "globalId": "TodoTask",
  "actions": undefined,
  "lifecycles": undefined
}

Next article: Server customization part 4/6

Maxime CastresGrowth Engineer

Maxime started to code in 2015 and quickly joined the Growth team of Strapi. He particularly likes to create useful content for the awesome Strapi community. Send him a meme on Twitter to make his day: @MaxCastres

How tos·12 min read

How To Build A Static Blog Using Jekyll And Strapi

Static sites deliver fast performance but present a content management challenge: how do you let writers update blog...

·August 3, 2025
Build a Blog with Astro, Strapi, and Tailwind CSS
How tos·22 min read

How to Build a Blog with Astro, Strapi, and Tailwind CSS

This article has been updated to use Astro 4 and Strapi 5 by Juliet Ofoegbu.

·October 20, 2023
Build a CRUD App with Flutter and Strapi
How tos·12 min read

How to Build a Simple CRUD Application Using Flutter & Strapi

This article has been updated to use Strapi 5 and REST API by Ekekenta Odionyefe.

·August 23, 2023