Skip to main content

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

  1. Schema Definition

    • Always use Zod for schema validation
    • Leverage zaf for form field integration
    • Keep schemas modular and reusable
  2. Component Structure

    • Follow Svelte 5 conventions
    • Use snippets instead of slots
    • Implement proper type definitions
  3. Asset Management

    • Group related assets
    • Use appropriate asset components
    • Handle asset metadata properly
  4. 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 renderer
  • RenderBlocks.renderComponent: Helper for component integration

Form Fields

  • BlockField.Root: Main block field component
  • FormField: Base form field components
  • zaf: Form field schema helper

Rich Text Editor

  • RichTextEditor.Root: Main editor component
  • RichTextEditor.schema: Editor schema definition
  • RichTextEditor.tiptapExtensions: Available editor extensions

Contributing

  1. Fork the repository
  2. Create your feature branch
  3. Commit your changes
  4. Push to the branch
  5. Create a new Pull Request

License

[License Type] - see LICENSE file for details