CMS Package
Under Construction, this package is not ready for use
A flexible, block-based CMS system built with SvelteKit and TypeScript, designed for creating dynamic content pages with a modular architecture.
Features
- 🧱 Block-based content management
- 🎨 Rich text editing capabilities
- 🖼️ Asset management and integration
- 📝 Form field abstractions
- 🔒 Type-safe schema definitions
- 🎯 Component-driven architecture
Installation
pnpm add @repo/cms
Core Concepts
Blocks
Blocks are the fundamental building units of the CMS. Each block represents a reusable content component with:
- A schema definition (using Zod)
- A component for rendering
- Optional metadata and configuration
Example block definition:
const blocks = {
content: {
label: 'Content',
schema: z.object({
content: zaf(RichTextEditor.schema, { component: RichTextEditor.Root }),
}),
component: RenderBlocks.renderComponent(MyComponent, {}),
}
}
Block Fields
Block fields provide the interface for managing blocks. They support:
- Adding/removing blocks
- Reordering blocks
- Configuring block content
- Validation through schemas
Rich Text Editor
Built-in rich text editing capabilities using TipTap:
const schema = z.object({
content: zaf(RichTextEditor.schema, {
component: RichTextEditor.Root
})
})
Asset Management
Integrated asset handling with:
- Asset grouping
- Autocomplete field for asset selection
- Asset metadata support
const schema = z.object({
image: zaf(z.string(), {
component: AssetAutocompleteField,
group: 'assets'
})
})
Usage Examples
Creating a Landing Page Block
export const landingPageBlocks = {
hero: {
label: 'Hero',
schema: z.object({
title: zaf(z.string(), { component: FormField.Textarea }),
description: zaf(RichTextEditor.schema, { component: RichTextEditor.Root }),
image: zaf(z.string(), {
component: AssetAutocompleteField,
group: 'assets',
}),
buttons: z.array(buttonBlockSchema),
}),
component: RenderBlocks.renderComponent(Hero, {}),
}
}
Rendering Blocks
<script lang="ts">
import { RenderBlocks } from '@repo/cms'
const { blocks, values } = $props()
</script>
<RenderBlocks.Root {blocks} {values} />
Best Practices
-
Schema Definition
- Always use Zod for schema validation
- Leverage
zaffor form field integration - Keep schemas modular and reusable
-
Component Structure
- Follow Svelte 5 conventions
- Use snippets instead of slots
- Implement proper type definitions
-
Asset Management
- Group related assets
- Use appropriate asset components
- Handle asset metadata properly
-
Block Organization
- Keep blocks focused and single-purpose
- Reuse common blocks through composition
- Maintain clear naming conventions
API Reference
RenderBlocks
The main component for rendering block content:
RenderBlocks.Root: Main block rendererRenderBlocks.renderComponent: Helper for component integration
Form Fields
BlockField.Root: Main block field componentFormField: Base form field componentszaf: Form field schema helper
Rich Text Editor
RichTextEditor.Root: Main editor componentRichTextEditor.schema: Editor schema definitionRichTextEditor.tiptapExtensions: Available editor extensions
Contributing
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Create a new Pull Request
License
[License Type] - see LICENSE file for details