Collection Builder Guide
Complete guide to creating and managing content collections using the visual collection builder in SveltyCMS
Last updated: 10/5/2025
Collection Builder Guide
Overview
The Collection Builder is a visual tool for creating and managing content collections in SveltyCMS. It provides an intuitive interface for defining content structures, organizing collections into categories, and configuring fields using the modern widget system.
(GUI)"] CODE["TypeScript Schema
(Code)"] end subgraph "Schema Processing" DIFF["Schema Comparison
(collectionSchemaWarnings.ts)"] WARN{"Breaking
Changes?"} end subgraph "User Protection" MODAL["Data Loss Modal
(modal-schema-warning.svelte)"] CONFIRM["User Confirmation"] end subgraph "Persistence" API["API: /content-structure"] DB["Database"] end GUI --> DIFF CODE --> DIFF DIFF --> WARN WARN -->|Yes| MODAL WARN -->|No| API MODAL --> CONFIRM CONFIRM -->|Approved| API CONFIRM -->|Cancelled| GUI API --> DB style GUI fill:#4CAF50,color:#fff style CODE fill:#2196F3,color:#fff style MODAL fill:#FF5722,color:#fff style WARN fill:#FFC107,color:#000
Note: The Collection Builder is currently in beta and under active development. Some features may not be fully functional yet. Report issues on GitHub.
Roadmap
⏸️ Deferred:
- LeftSidebar DND ordering - Enable drag-and-drop reordering directly in sidebar (TreeView has built-in support)
🔧 Not Yet Integrated:
- Widget Factory - Visual widget creation tool
- Marketplace integration - Download widgets from
marketplace.sveltycms.com
Getting Started
Accessing the Collection Builder
Navigation Path: /config/collectionbuilder
Requirements:
- User must have
adminrole OR - User must have collection management permissions
Collection Builder Interface
The Collection Builder has two main views:
-
Category Board View (
/config/collectionbuilder)- Visual board showing collection categories
- Drag-and-drop organization
- Create new categories and collections
-
Collection Editor View (
/config/collectionbuilder/[action]/[collectionPath])- Edit or create individual collections
- Configure collection settings
- Manage collection fields
Category Management
Understanding Categories
Collections are organized into categories for better organization and management:
- Category: A folder-like container for related collections
- Nested Structure: Categories and collections can be nested
- Drag-and-Drop: Rearrange categories and collections visually
- Visual Organization: Each category has a name and icon
Creating Categories
Step-by-Step:
- Navigate to
/config/collectionbuilder - Click “Add Category” button
- Fill in category details:
- Name: Unique category name (e.g., “Blog”, “Products”, “Pages”)
- Icon: Select an icon from IconPicker
- Click “Submit” to create
- Category appears as a new column in the board
Editing Categories
To Edit:
- Click on a category to open edit modal
- Modify:
- Category name
- Category icon
- Save changes
- Updates appear immediately in the board
Moving Collections Between Categories
Drag-and-Drop:
- Click and hold a collection card
- Drag to desired category column
- Drop to move
- Click “Save” button to persist changes
Collection Management
Creating a New Collection
Method 1: From Category Board
- Navigate to
/config/collectionbuilder - Click ”+” icon in a category column
- Enter collection name
- System navigates to collection editor
Method 2: Direct Creation
- Navigate to
/config/collectionbuilder/create/[collectionName] - Fill in collection details
- Configure fields
- Click “Save” to create
Collection Editor
The collection editor has two main tabs:
Tab 1: Collection Form (Basic Settings)
Collection Information:
Name (required):
- Display name for the collection
- Used in navigation and UI
- Auto-generates slug and database name
- Example: “Blog Posts”
Icon (required):
- Visual identifier for the collection
- Uses IconPicker for icon selection
- Example:
mdi:post
Slug (auto-generated):
- URL-friendly identifier
- Auto-generated from name
- Used in routing:
/collection/[slug] - Example: “blog_posts”
- Can be manually edited if needed
Database Name (read-only):
- Internal database collection name
- Auto-generated: lowercase with underscores
- Example: “blog_posts”
- Used for database operations
Description (optional):
- Brief description of collection purpose
- Displayed in admin interface
- Helpful for documentation
Status (required):
- Published: Collection is active and accessible
- Unpublished: Collection exists but is not publicly accessible
- Draft: Collection is in development
Collection Settings (Advanced):
- Multi-language support
- Automatic timestamps (createdAt, updatedAt)
- SEO metadata fields
- Custom permissions
Tab 2: Collection Widgets (fields Configuration)
This tab manages the fields (widgets) that make up your collection’s content structure.
Features:
- Visual list of all fields
- Drag-and-drop field reordering
- Add/edit/delete fields
- Field preview
Adding fields to Collections
Step-by-Step Process:
-
Open Collection Editor
- Navigate to collection or create new one
- Switch to “Widgets” tab
-
Add New Field
- Click “Add Field” button
- Modal opens: “Select a Widget”
-
Choose Widget Type
- Browse available widgets:
- Input: Single-line text input
- Textarea: Multi-line text
- RichText: WYSIWYG editor
- Number: Numeric input
- Date: Date picker
- DateTime: Date and time picker
- Boolean: True/false toggle
- Select: Dropdown selection
- MediaUpload: File/image upload
- Relation: Link to other collections
- Array: Multiple values
- Custom Widgets: Additional widget types
- Click widget to select
- Click “Submit”
- Browse available widgets:
-
Configure Widget
- Second modal opens: “Define your Widget”
- Three tabs available:
Widget Configuration Tabs
Tab 1: Default Settings
Basic Configuration:
Label (required):
- Display name for the field
- Shown in forms and UI
- Example: “Post Title”, “Author Name”
Database Field Name (required):
- Internal field identifier
- Used in database and API
- Snake_case recommended
- Example: “post_title”, “author_name”
Required:
- Toggle: Is this field mandatory?
- Validation enforced on save
Translated:
- Enable multi-language support
- Stores values per language
- Uses language-specific fields in database
Widget-Specific Options:
Different widgets have different configuration options:
Text Input Widget:
- Placeholder text
- Min/max length
- Character counter
- Input type (text, email, URL, tel, etc.)
- Pattern validation (regex)
RichText Widget:
- Toolbar configuration
- Allowed HTML tags
- Media upload settings
- Maximum content length
Number Widget:
- Min/max values
- Step increment
- Decimal places
- Number formatting (currency, percentage)
MediaUpload Widget:
- Allowed file types (image/, video/, .pdf, etc.)
- Maximum file size (MB)
- Image dimensions (min/max width/height)
- Multiple file upload toggle
- Crop settings
Relation Widget:
- Target collection (which collection to link to)
- Display field (which field to show in dropdown)
- Multiple selection toggle
- Nested editing capability
Select Widget:
- Options list (add multiple options)
- Default value
- Allow multiple selection
- Searchable dropdown
Tab 2: Specific Settings
Advanced widget-specific configurations:
- Display settings (show in lists, cards, previews)
- Validation rules (custom validation logic)
- Default values
- Help text
- Conditional visibility
Tab 3: Permissions
Field-level access control:
- Read permissions
- Write permissions
- Delete permissions
- Role-based restrictions
- Save Widget Configuration
- Click “Save” button
- Widget added to collection
- Appears in fields list
Managing Existing fields
Reorder fields:
- Drag field up or down in the list
- Drop in desired position
- Click “Save” to persist order
Edit Field:
- Click field card in the list
- Widget configuration modal opens
- Modify settings
- Click “Save”
Delete Field:
- Click delete icon on field card
- Confirm deletion
- Field removed from collection
- Click “Save” to persist
Saving Collections
Save Process:
-
Validate Form:
- Check all required fields filled
- Verify widget configurations
- Ensure unique collection name
-
Click Save Button:
- Located at top right of editor
- Saves both Collection Form and Widgets tabs
-
Confirmation:
- Toast notification: “Collection Saved”
- System compiles collection schema
- Database tables/collections created
Deleting Collections
Delete Process (Edit mode only):
- Open collection in editor
- Click “Delete” button (red button)
- Confirmation dialog appears
- Confirm deletion
- Collection removed from system
- Associated database table preserved (archival)
Content Structure API
Saving Changes
When you make changes to categories and collections, use the “Save” button to persist:
API Endpoint: POST /api/content-structure
Operations Tracked:
- create: New category or collection
- update: Modified properties (icon, name)
- move: Changed parent or order
- rename: Name changes
- delete: Removed items
Batch Operations:
- All changes saved together
- Atomic operations (all or nothing)
- Rollback on errors
Widget System Integration
Available Widgets
SveltyCMS uses a modern widget architecture with three pillars:
- Definition Pillar: Widget metadata and schema
- Input Pillar: Data entry component
- Display Pillar: Data display component
Core Widgets:
- Input (single-line text)
- Textarea (multi-line text)
- RichText (WYSIWYG editor)
- Number (numeric input)
- Boolean (toggle)
- Date/DateTime (date pickers)
- MediaUpload (file/image)
- Relation (collection links)
- Select (dropdown)
- Array (multiple values)
Custom Widgets:
- Located in
src/widgets/custom/ - Can be added to extend functionality
- Follow same three-pillar architecture
Widget Factory System
Widgets are created using the factory pattern:
import { createWidget } from '@widgets/widgetFactory';
const widget = createWidget({
Name: 'my-widget',
Icon: 'mdi:my-icon',
Description: 'My custom widget',
GuiSchema: {
/* configuration */
}
});
See Widget Architecture for details.
Best Practices
Collection Design
Naming Conventions:
- Use descriptive, clear names
- Keep collection names concise
- Use singular form (e.g., “Post” not “Posts”)
- Avoid special characters
Organization:
- Group related collections in categories
- Use consistent naming patterns
- Plan collection structure before creating
- Document collection purposes
Field Configuration:
- Mark truly required fields only
- Provide helpful labels and descriptions
- Use appropriate widget types
- Configure validation rules
- Set sensible defaults
Performance
Optimize Field Count:
- Use only necessary fields
- Avoid excessive relation fields
- Consider field index requirements
- Plan for scalability
Indexing:
- Database indexes created automatically
- Searchable fields are indexed
- Sortable fields are indexed
- Consider query patterns
Security
Permissions:
- Set field-level permissions carefully
- Use least privilege principle
- Review permission inheritance
- Test permissions thoroughly
Validation:
- Configure input validation
- Set length limits
- Validate file types and sizes
- Use server-side validation
Troubleshooting
Common Issues
“Collection name already exists”:
- Collection names must be unique
- Check existing collections
- Use different name or edit existing
“Invalid widget configuration”:
- Check all required fields filled
- Verify widget-specific settings
- Review validation errors in form
“Cannot save changes”:
- Check for validation errors
- Verify permissions
- Review browser console for errors
- Check server logs
“Widgets not appearing”:
- Ensure widgets are activated in Widget Management
- Check widget store initialization
- Verify widget imports
- See Widget Management
Debug Information
Browser Console:
- Check for JavaScript errors
- Review network requests
- Inspect collection state
- Verify widget loading
Server Logs:
- Check
/logs/app.log - Look for validation errors
- Review permission denials
- Monitor database operations
Known Limitations (Beta)
Current Limitations:
- Some advanced widget configurations may not be fully functional
- Nested collection structures have depth limits
- Bulk operations on multiple collections limited
- Real-time Collaboration: Native SSE-based activity stream and AI assistant integrated into the UI.
Workarounds:
- Save frequently to avoid data loss
- Test configurations in development first
- Report issues on GitHub for fixes
API Reference
Content Structure Endpoint
POST /api/content-structure
Content-Type: application/json
{
"operations": [
{
"type": "create",
"node": {
"name": "New Category",
"icon": "mdi:folder",
"nodeType": "category"
}
},
{
"type": "move",
"node": {
"_id": "123",
"parentId": "456",
"order": 2
}
}
]
}
Collection Schema
interface Schema {
_id: string;
name: string;
slug: string;
icon: string;
description?: string;
status: 'published' | 'unpublished' | 'draft';
fields: FieldInstance[];
permissions?: PermissionConfig;
createdAt: Date;
updatedAt: Date;
}
interface FieldInstance {
widget: WidgetDefinition;
label: string;
db_fieldName: string;
required?: boolean;
translated?: boolean;
permissions?: FieldPermissions;
// Widget-specific properties...
}
Data Loss Warnings
SveltyCMS protects your data with built-in breaking change detection:
How It Works
When you modify a collection schema (via GUI or code), the system compares the new schema against the existing one and warns about:
| Change Type | Risk Level | Description |
|---|---|---|
field_removed |
🔴 Data Loss | Field deleted - existing data will be lost |
type_changed |
🟡 Warning | Widget type changed - data format may become incompatible |
required_added |
🟡 Warning | New required field - existing entries become invalid |
unique_added |
🟡 Warning | New unique constraint - may cause duplicate conflicts |
GUI Protection
When saving a collection with breaking changes, a confirmation modal displays:
- List of detected breaking changes
- Data loss risk indicators
- Required checkbox confirmation for data loss changes
Code-Level Warnings
The schema comparison engine (collectionSchemaWarnings.ts) can be used programmatically:
import { analyzeSchemaChanges } from '@utils/collectionSchemaWarnings';
const result = analyzeSchemaChanges(oldSchema, newSchema);
if (result.hasDataLoss) {
console.warn('⚠️ Data loss detected:', result.summary);
}
CMS Comparison
Why Choose SveltyCMS?
Enterprise-Ready Features:
- 🔒 Data Protection - Built-in schema change warnings prevent accidental data loss
- 🏗️ Dual Workflow - Visual builder for marketers, TypeScript schemas for developers
- ⚡ Performance - SvelteKit’s SSR and hydration outperforms React/Vue alternatives
- 🔧 Type Safety - End-to-end TypeScript from schema to API to frontend
- 🏢 Multi-Tenant - Built-in support for multiple sites/clients from one instance
- 🔄 Hot Reload - Collections compile instantly via Vite watcher
Extensible Widget Ecosystem:
SveltyCMS uses a 3-pillar widget architecture:
- Core Widgets - Essential fields (Text, Number, Date, etc.) included by default
- Custom Widgets - Organization-specific widgets you create
- Marketplace Widgets - Community widgets from marketplace.sveltycms.com
Coming Soon: The Widget Factory will allow creating custom widgets visually, and the marketplace will enable sharing and monetizing widgets.
How SveltyCMS Compares
| Feature | SveltyCMS | WordPress | Drupal | Directus | Strapi | PayloadCMS | Sanity |
|---|---|---|---|---|---|---|---|
| Architecture | Both | Visual | Both | Visual | Both | Code-first | Both |
| TypeScript Native | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
| Headless | ✅ | Plugin | Plugin | ✅ | ✅ | ✅ | ✅ |
| Visual Builder | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| Data Loss Warnings | ✅ | ❌ | ❌ | ✅ | ⚠️ | ⚠️ | ⚠️ |
| Widget System | 3-Pillar | Plugin-based | Module | Interface | Plugin | Field | Schema |
| Self-Hosted | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | Cloud |
| Multi-Tenant | ✅ | ❌ | ⚠️ | ✅ | ⚠️ | ✅ | ✅ |
| Modern Framework | SvelteKit | PHP | PHP | Vue | React | React | React |
Key Differentiators
vs WordPress/Drupal (Traditional CMS):
- Modern JavaScript stack vs PHP
- True headless architecture
- Type-safe content modeling
vs Directus (Visual-first):
- Similar visual approach
- SvelteKit performance benefits
- 3-pillar widget architecture
vs PayloadCMS (Code-first):
- SveltyCMS supports BOTH visual and code workflows
- PayloadCMS is code-only (no GUI builder)
- Similar TypeScript-first approach
vs Strapi (Popular headless):
- Modern SvelteKit vs older React
- Built-in data loss warnings
- More flexible widget system
vs Sanity (Cloud-native):
- Self-hosted by default (no cloud lock-in)
- Similar schema flexibility
- More traditional CMS workflow
Related Documentation
Architecture
- Compilation Pipeline - How collections are compiled (compile.ts + vite.config.ts)
- Initialization Workflow - System startup and collection loading
Widgets
- Widget Architecture - Modern widget system design
- Widget Management - Managing widgets
Guides
- Content Management - Working with collections
- Permission System - Roles and permissions
- Multi-Tenant Setup - Tenant configuration
Feedback: Report issues on GitHub