Collections
Define content types with TypeScript schemas and field validation. Collections are the foundation of your content model in CatCMS. [object Object]
Overview
Collections define your content types using TypeScript schemas. Each collection automatically gets:
- Type-safe database schema
- Automatic API endpoints
- Admin UI for content management
- Field validation and constraints
- Version control through git
Two Types of Collections
Config-Managed Collections:
- Defined in TypeScript files (
src/collections/*.collection.ts) - Version controlled with your codebase
- Automatically synced on app startup
- Locked from editing in the admin UI (marked with βConfigβ badge)
- Type-safe with IDE autocomplete
UI-Created Collections:
- Created and edited through the admin interface
- Stored directly in the database
- Not version controlled
- Fully editable in the UI
- Great for rapid prototyping
Creating Collections
Basic Collection
Create a new file in src/collections/ with a .collection.ts extension:
// src/collections/blog-posts.collection.ts
import { CollectionConfig } from 'catcms-core'
export const blogPostsCollection: CollectionConfig = {
name: 'blog_posts',
displayName: 'Blog Posts',
description: 'Articles and blog content',
schema: {
type: 'object',
properties: {
title: {
type: 'string',
required: true,
minLength: 3,
maxLength: 200,
},
slug: {
type: 'slug',
required: true,
},
content: {
type: 'richtext',
required: true,
},
excerpt: {
type: 'textarea',
maxLength: 500,
},
author: {
type: 'reference',
collection: 'users',
required: true,
},
publishDate: {
type: 'datetime',
required: true,
},
status: {
type: 'select',
enum: ['draft', 'published', 'archived'],
default: 'draft',
},
},
},
icon: 'π',
color: 'blue',
managed: true,
isActive: true,
defaultSort: 'created_at',
defaultSortOrder: 'desc',
listFields: ['title', 'author', 'publishDate', 'status'],
searchFields: ['title', 'excerpt', 'content'],
}Blog Posts Collection
Syncing Collections
Collections are automatically synced on server startup. You can also manually sync:
# Collections auto-sync on server restart
npm run dev
# Or manually sync
npm run sync-collectionsSync Collections
Field Types
CatCMS supports 30+ field types for building rich content schemas:
Text Fields
- Name
string- Type
- string
- Description
Single-line text input. Use for titles, names, short text.
- Name
textarea- Type
- string
- Description
Multi-line plain text. Use for descriptions, notes, long text.
- Name
email- Type
- string
- Description
Email with validation. Use for contact emails, author info.
- Name
url- Type
- string
- Description
URL with validation. Use for links, external resources.
- Name
slug- Type
- string
- Description
URL-friendly identifier. Use for page URLs, SEO paths.
- Name
color- Type
- string
- Description
Color picker. Use for theme colors, UI customization.
Rich Content
- Name
richtext- Type
- string
- Description
WYSIWYG HTML editor. Use for blog posts, articles, formatted content.
- Name
markdown- Type
- string
- Description
Markdown editor. Use for documentation, technical content.
- Name
json- Type
- object
- Description
JSON editor. Use for structured data, API responses.
Numbers and Dates
- Name
number- Type
- number
- Description
Numeric input. Use for prices, quantities, ratings.
- Name
date- Type
- string
- Description
Date picker (no time). Use for birthdays, deadlines.
- Name
datetime- Type
- string
- Description
Date and time picker. Use for publish dates, events.
Selections
- Name
select- Type
- string
- Description
Dropdown (single choice). Use for categories, status fields.
- Name
multiselect- Type
- array
- Description
Dropdown (multiple choices). Use for tags, multiple categories.
- Name
radio- Type
- string
- Description
Radio buttons. Use for status, visibility options.
- Name
checkbox- Type
- boolean
- Description
Boolean checkbox. Use for feature toggles, flags.
Media and Files
- Name
media- Type
- string
- Description
Image/media picker. Use for featured images, avatars.
- Name
file- Type
- string
- Description
File upload. Use for PDFs, documents, downloads.
Relationships
- Name
reference- Type
- string
- Description
Reference to another collection. Use for authors, categories.
- Name
array- Type
- array
- Description
Array of items. Can contain any field type.
Validation
Built-in Validators
export const productsCollection: CollectionConfig = {
name: 'products',
displayName: 'Products',
schema: {
type: 'object',
properties: {
name: {
type: 'string',
required: true,
minLength: 3,
maxLength: 200,
},
sku: {
type: 'string',
required: true,
pattern: '^[A-Z0-9-]+$', // Only uppercase, numbers, hyphens
},
price: {
type: 'number',
required: true,
minimum: 0,
maximum: 999999,
},
email: {
type: 'email',
required: true,
},
url: {
type: 'url',
required: false,
},
status: {
type: 'select',
enum: ['draft', 'active', 'archived'],
default: 'draft',
},
},
},
managed: true,
isActive: true,
}Field Validation
Validation Rules
- required - Field must have a value
- minLength / maxLength - String length constraints
- minimum / maximum - Number range constraints
- pattern - Regular expression validation
- enum - Must be one of specified values
- default - Default value if not provided
Examples
E-commerce Product
export const productsCollection: CollectionConfig = {
name: 'products',
displayName: 'Products',
description: 'E-commerce product catalog',
schema: {
type: 'object',
properties: {
name: {
type: 'string',
required: true,
},
sku: {
type: 'string',
required: true,
},
price: {
type: 'number',
required: true,
minimum: 0,
},
description: {
type: 'richtext',
},
images: {
type: 'array',
items: {
type: 'media',
accept: 'image/*',
},
},
category: {
type: 'select',
enum: ['electronics', 'clothing', 'home', 'sports'],
},
inStock: {
type: 'boolean',
default: true,
},
tags: {
type: 'array',
items: { type: 'string' },
},
},
},
icon: 'ποΈ',
managed: true,
isActive: true,
}Product Collection
Documentation Page
export const docsCollection: CollectionConfig = {
name: 'documentation',
displayName: 'Documentation',
schema: {
type: 'object',
properties: {
title: {
type: 'string',
required: true,
},
slug: {
type: 'slug',
required: true,
},
content: {
type: 'markdown',
required: true,
},
category: {
type: 'select',
enum: ['getting-started', 'api', 'guides', 'reference'],
},
order: {
type: 'number',
default: 0,
},
published: {
type: 'boolean',
default: false,
},
},
},
icon: 'π',
managed: true,
isActive: true,
}Docs Collection
Event Management
export const eventsCollection: CollectionConfig = {
name: 'events',
displayName: 'Events',
schema: {
type: 'object',
properties: {
title: {
type: 'string',
required: true,
},
description: {
type: 'richtext',
},
startDate: {
type: 'datetime',
required: true,
},
endDate: {
type: 'datetime',
required: true,
},
location: {
type: 'string',
},
virtualLink: {
type: 'url',
},
capacity: {
type: 'number',
minimum: 1,
},
registration: {
type: 'boolean',
default: false,
},
organizer: {
type: 'reference',
collection: 'users',
},
},
},
icon: 'π
',
managed: true,
isActive: true,
}Events Collection
Using Collections
Query Content
// Get all content from a collection
const posts = await db
.select()
.from(content)
.where(eq(content.collection_id, 'blog_posts'))
.orderBy(desc(content.created_at))
.limit(10)
// Get single content item
const post = await db.select().from(content).where(eq(content.id, postId)).get()
// Search content
const results = await db
.select()
.from(content)
.where(and(eq(content.collection_id, 'blog_posts'), like(content.title, '%search%')))
.all()Fetch Collection Content
API Endpoints
Collections automatically get REST API endpoints:
/api/collections/{collection}/content /api/content/{id} /admin/content Auth required/admin/content/{id} Auth required/admin/content/{id} Auth requiredBest Practices
Collection Design Tips
- Use descriptive field names that reflect your content model - Set appropriate validation rules to maintain data quality - Use references for relationships between collections - Enable search on fields that users will query frequently - Set reasonable defaults for optional fields
Performance Considerations
- Limit the number of fields in
listFieldsto improve list performance - Use appropriate field types (e.g.,selectinstead ofstringfor fixed options) - Index frequently queried fields in your database