Skip to main content

Schema Overview

BlockSlides extends the base ProseMirror schema with slide focused nodes to create a powerful document structure for presentations.

Document Structure

Every BlockSlides document follows this hierarchy:

Document → slide+ → row+ → column+ → block content

Document Node

  • Document → slide+: Every document starts as a stack of one or more slides.

Slide Node

The slide node is the top-level container for each presentation slide:

  • Wraps one or more row nodes
  • Carries slide-level attributes (classes, theming, unique ID)
  • Enables per-slide styling and behavior
{
type: 'slide',
attrs: { id: 'unique-slide-id' },
content: [/* row nodes */]
}

Row Node

The row node (@blockslides/extension-row) is a horizontal flex container:

  • Can host column nodes or fallback block content
  • Supports layout presets via data-layout attribute
  • Common layouts: 1, 1-1, 1-2, 2-1, 1-1-1, 1-2-1
{
type: 'row',
attrs: {
layout: '1-1',
className: 'custom-classes'
},
content: [/* column nodes */]
}

Column Node

The column node (@blockslides/extension-column) is a vertical flex container inside a row:

  • Controls alignment, padding, and stacking of nested blocks
  • Can contain other rows for complex grid layouts
  • Supports custom styling and attributes
{
type: 'column',
attrs: {
className: 'flex items-center justify-center'
},
content: [/* block content or nested rows */]
}

Block Content

Columns can contain any of these block-level nodes:

  • Paragraphs: Basic text content
  • Headings: Levels 1-6
  • Lists: Bullet lists and ordered lists
  • Images: Image blocks with layout options
  • Videos: YouTube embeds and more
  • Code Blocks: Syntax-highlighted code
  • Blockquotes: Quoted content
  • Tables: Structured data
  • And more: Custom nodes via extensions

Marks

Text within block content can be styled with marks:

  • bold, italic, underline
  • strikethrough, code
  • highlight with colors
  • links with URLs
  • font-family and font-size
  • text color and text shadow
  • superscript and subscript

All marks are defined under packages/core/src/schema/marks and follow standard ProseMirror specs.

Schema Examples

Single Slide Document

const singleSlideDoc = {
type: 'doc',
content: [
{
type: 'slide',
attrs: { id: 'slide-1' },
content: [
{
type: 'row',
attrs: { layout: '1' },
content: [
{
type: 'column',
content: [
{
type: 'heading',
attrs: { level: 2 },
content: [{ type: 'text', text: 'Welcome' }],
},
{
type: 'paragraph',
content: [{ type: 'text', text: 'This is my first slide' }],
},
],
},
],
},
],
},
],
};

Three-Column Layout

const threeColumnSlide = {
type: 'slide',
attrs: { id: 'feature-grid' },
content: [
{
type: 'row',
attrs: {
layout: '1-1-1',
className: 'bg-slate-900 text-white'
},
content: [
{
type: 'column',
attrs: {
className: 'p-12 border-r border-white/10'
},
content: [
{
type: 'heading',
attrs: { level: 3 },
content: [{ type: 'text', text: 'Feature 1' }],
},
{
type: 'paragraph',
content: [
{ type: 'text', text: 'Description of feature 1' },
],
},
],
},
{
type: 'column',
attrs: {
className: 'p-12 border-r border-white/10'
},
content: [/* Feature 2 content */],
},
{
type: 'column',
attrs: {
className: 'p-12'
},
content: [/* Feature 3 content */],
},
],
},
],
};

Image and Text Layout

const heroSlide = {
type: 'slide',
attrs: { id: 'hero-slide' },
content: [
{
type: 'row',
attrs: { layout: '2-1' },
content: [
{
type: 'column',
content: [
{
type: 'imageBlock',
attrs: {
src: 'https://example.com/hero.jpg',
layout: 'cover',
fullBleed: true,
alt: 'Hero image',
},
},
],
},
{
type: 'column',
attrs: {
className: 'bg-slate-900 text-white flex flex-col justify-center p-12',
},
content: [
{
type: 'heading',
attrs: { level: 2 },
content: [{ type: 'text', text: 'Bold Vision' }],
},
{
type: 'paragraph',
content: [
{ type: 'text', text: 'Your compelling message here.' },
],
},
],
},
],
},
],
};

Extending the Schema

You can extend or override any node or mark by creating custom extensions. All nodes and marks follow standard ProseMirror specs, making it easy to customize for your use case.

The @blockslides/extension-kit package provides all standard extensions enabled by default. You can configure which extensions to use:

import { ExtensionKit } from "@blockslides/extension-kit";

const editor = useEditor({
extensions: [
ExtensionKit.configure({
// Disable specific extensions
bold: false,
// Or configure them
heading: {
levels: [1, 2, 3],
},
}),
],
});

Next Steps