Custom Content Types in Strapi
Content Types in Strapi come in three varieties: Collection Type (list of entries), Single Type (one entry — site settings, home page), Component (reusable group of fields). All are described via JSON schema in src/api/ or src/components/.
Collection Type
// src/api/product/content-types/product/schema.json
{
"kind": "collectionType",
"collectionName": "products",
"info": {
"singularName": "product",
"pluralName": "products",
"displayName": "Product"
},
"options": { "draftAndPublish": true },
"pluginOptions": { "i18n": { "localized": true } },
"attributes": {
"name": {
"type": "string",
"required": true,
"pluginOptions": { "i18n": { "localized": true } }
},
"slug": { "type": "uid", "targetField": "name" },
"description": {
"type": "richtext",
"pluginOptions": { "i18n": { "localized": true } }
},
"price": { "type": "decimal", "required": true, "min": 0 },
"stock": { "type": "integer", "default": 0, "min": 0 },
"images": { "type": "media", "multiple": true, "allowedTypes": ["images"] },
"category": {
"type": "relation",
"relation": "manyToOne",
"target": "api::category.category",
"inversedBy": "products"
},
"specs": {
"type": "component",
"repeatable": true,
"component": "product.spec"
}
}
}
Single Type
// src/api/homepage/content-types/homepage/schema.json
{
"kind": "singleType",
"collectionName": "homepages",
"info": {
"singularName": "homepage",
"pluralName": "homepages",
"displayName": "Home Page"
},
"attributes": {
"hero": { "type": "component", "component": "sections.hero", "repeatable": false },
"sections": { "type": "dynamiczone", "components": ["sections.text", "sections.gallery", "sections.cta"] },
"seo": { "type": "component", "component": "shared.seo", "repeatable": false }
}
}
Component
// src/components/shared/seo.json
{
"collectionName": "components_shared_seos",
"info": { "displayName": "SEO", "icon": "search" },
"attributes": {
"metaTitle": { "type": "string", "maxLength": 60 },
"metaDescription": { "type": "text", "maxLength": 160 },
"ogImage": { "type": "media", "multiple": false, "allowedTypes": ["images"] },
"noIndex": { "type": "boolean", "default": false }
}
}
API Requests to Content Types
# Collection Type
GET /api/products?populate=images,category,specs&sort=createdAt:desc
# Single Type
GET /api/homepage?populate=hero,sections,seo
# Dynamic Zone — need to populate each component
GET /api/homepage?populate[sections][populate]=*
Programmatic Entry Creation
// In Strapi controller or service
await strapi.entityService.create('api::product.product', {
data: {
name: 'New Product',
slug: 'new-product',
price: 1500,
publishedAt: new Date(),
},
})
Timeline
Creating 3–5 content types with components via Content-Type Builder and JSON takes 1–2 days.







