Features

Everything you need to build content-driven Astro sites.

Page Editor

Named regions, composable blocks

Every page is divided into named regions — hero, content, features, sidebar, bottom — that you define per content type. Editors add blocks to each region, reorder them with drag-and-drop, and see exactly how the page is structured. No guessing where content will appear.

  • Blocks show their type, title, and position at a glance
  • Click + to add blocks from the block library to any region
  • Drag handles to reorder blocks within or between regions
  • Sidebar shows page info, SEO meta, and accessibility score
Page Editor
class="text-slate-500">// This page has 4 regions with 10 blocks:
class="text-slate-500">//
class="text-slate-500">// HERO (2)
class="text-slate-500">//   1. Hero         — heading, CTA buttons
class="text-slate-500">//   2. Code Terminal — install commands
class="text-slate-500">//
class="text-slate-500">// CONTENT (1)
class="text-slate-500">//   1. Stat Bar      — key metrics
class="text-slate-500">//
class="text-slate-500">// FEATURES (4)
class="text-slate-500">//   1. Feature Grid  — 9 feature cards
class="text-slate-500">//   2. Code Example  — developer experience
class="text-slate-500">//   3. Code Example  — content modeling
class="text-slate-500">//   4. Code Example  — navigation
class="text-slate-500">//
class="text-slate-500">// BOTTOM (2)
class="text-slate-500">//   1. Comparison Table — vs competitors
class="text-slate-500">//   2. CTA Button       — get started
WollyCMS page editor showing the homepage with named regions containing Hero, Code Terminal, Stat Bar, Feature Grid, and other block types
The WollyCMS page editor — this is actually the homepage of this very site, managed through WollyCMS

Block Editor

Every field typed, every block editable

Click any block to open its field editor. Text fields, rich text, media uploads, selects, booleans, repeaters — each field type has a purpose-built editor. Block types define their own field schemas, so the editing experience adapts to the content.

  • Rich text editor with formatting, links, and media embeds
  • Repeater fields for lists of structured data (FAQ items, features, stats)
  • Media picker with upload, search, and alt text management
  • Shared blocks can be edited once and updated across all pages
Block Type Definition
class="text-slate-500">// Every block type defines its own field schema
class=class="text-amber-400">"text-sky-400">const heroBlock = {
  name: class="text-amber-400">"Hero",
  slug: class="text-amber-400">"hero",
  fields: [
    { name: class="text-amber-400">"heading",   type: class="text-amber-400">"text",     required: true },
    { name: class="text-amber-400">"subtitle",  type: class="text-amber-400">"text"                     },
    { name: class="text-amber-400">"eyebrow",   type: class="text-amber-400">"text"                     },
    { name: class="text-amber-400">"description", type: class="text-amber-400">"textarea"               },
    { name: class="text-amber-400">"cta_text",  type: class="text-amber-400">"text"                     },
    { name: class="text-amber-400">"cta_url",   type: class="text-amber-400">"url"                      },
    { name: class="text-amber-400">"style",     type: class="text-amber-400">"select",
      options: [class="text-amber-400">"home", class="text-amber-400">"interior"]                        }
  ]
}
WollyCMS block editor showing field editing for a hero block with heading, description, and CTA fields
Editing a block — each field type gets a purpose-built editor

Block Types

Create any block type you need

WollyCMS ships with common block types out of the box — hero, rich text, image, video, accordion, embed, and more. Need something custom? Define a JSON field schema and map it to an Astro component. Use AI coding tools or start from a template to create any block type you can imagine.

  • 16 block types included — hero, rich text, image, video, accordion, CTA, and more
  • Define custom block types with JSON schemas — use AI tools or pre-built templates to generate them
  • Each block type maps to an Astro component via a simple export
  • Field types: text, rich text, number, boolean, date, select, media, URL, repeater
src/lib/blocks.ts
class="text-slate-500">// Map each CMS block type to an Astro component
class="text-slate-500">// The class=class="text-amber-400">"text-sky-400">export name matches the block type slug

class=class="text-amber-400">"text-sky-400">export class="text-slate-300">{ default as hero } class=class="text-amber-400">"text-sky-400">from class="text-amber-400">"../blocks/Hero.astro";
class=class="text-amber-400">"text-sky-400">export class="text-slate-300">{ default as rich_text } class=class="text-amber-400">"text-sky-400">from class="text-amber-400">"../blocks/RichText.astro";
class=class="text-amber-400">"text-sky-400">export class="text-slate-300">{ default as image } class=class="text-amber-400">"text-sky-400">from class="text-amber-400">"../blocks/ImageBlock.astro";
class=class="text-amber-400">"text-sky-400">export class="text-slate-300">{ default as accordion } class=class="text-amber-400">"text-sky-400">from class="text-amber-400">"../blocks/Accordion.astro";
class=class="text-amber-400">"text-sky-400">export class="text-slate-300">{ default as code_terminal } class=class="text-amber-400">"text-sky-400">from class="text-amber-400">"../blocks/CodeTerminal.astro";
class=class="text-amber-400">"text-sky-400">export class="text-slate-300">{ default as feature_grid } class=class="text-amber-400">"text-sky-400">from class="text-amber-400">"../blocks/FeatureGrid.astro";
class=class="text-amber-400">"text-sky-400">export class="text-slate-300">{ default as stat_bar } class=class="text-amber-400">"text-sky-400">from class="text-amber-400">"../blocks/StatBar.astro";
class="text-slate-500">// Add your own custom block types here
class=class="text-amber-400">"text-sky-400">export class="text-slate-300">{ default as pricing_table } class=class="text-amber-400">"text-sky-400">from class="text-amber-400">"../blocks/PricingTable.astro";
class=class="text-amber-400">"text-sky-400">export class="text-slate-300">{ default as testimonial } class=class="text-amber-400">"text-sky-400">from class="text-amber-400">"../blocks/Testimonial.astro";
WollyCMS block types list showing all available block types including Hero, Rich Text, Accordion, Code Terminal, and more
All block types managed from the admin — define new ones with JSON field schemas

Menu Editor

Navigation with real depth

Create unlimited independent menus — main nav, footer, sidebar, mobile. Each supports deep nesting with parent/child relationships, container items for mega-menu dropdowns, and drag-and-drop reordering. Your Astro layout fetches menus by name and renders them however you want.

  • Unlimited menus, each with a unique slug for fetching
  • Deep nesting — no arbitrary depth limits
  • Container items group children without linking anywhere
  • Active state detection and breadcrumb helpers in @wollycms/astro
src/layouts/Base.astro
class="text-slate-500">---
class=class="text-amber-400">"text-sky-400">const menu = class=class="text-amber-400">"text-sky-400">await getWolly().menus.get(class="text-amber-400">"main");
class=class="text-amber-400">"text-sky-400">const footer = class=class="text-amber-400">"text-sky-400">await getWolly().menus.get(class="text-amber-400">"footer");
class="text-slate-500">---

<nav>
  class="text-slate-300">{menu.items.map((item) => (
    <a href={item.url}>
      class="text-slate-300">{item.title}
      {item.children?.length > 0 && (
        <ul class=class="text-amber-400">"dropdown">
          {item.children.map((c) => (
            <li><a href={c.url}>class="text-slate-300">{c.title}</a></li>
          ))}
        </ul>
      )}
    </a>
  ))}
</nav>
WollyCMS menu editor showing hierarchical navigation tree with nested menu items and drag-and-drop reordering
Menu editor with hierarchical nesting and drag-and-drop reordering

Content Types

Define any page type your site needs

Blog posts, landing pages, product pages, case studies — create content types with custom fields and region definitions. Each type controls what fields editors see and which block types are allowed in each region. Your content model adapts to your site, not the other way around.

  • Custom fields per type — text, date, taxonomy, media, repeater
  • Named regions with block type restrictions per region
  • Taxonomy system with vocabularies, terms, and hierarchies
  • Full TypeScript types in the API responses
API Response
class="text-slate-500">// GET /api/content/pages?type=blog_post
{
  class="text-amber-400">"data": [
    {
      class="text-amber-400">"type": class="text-amber-400">"blog_post",
      class="text-amber-400">"title": class="text-amber-400">"Building with WollyCMS",
      class="text-amber-400">"slug": class="text-amber-400">"building-with-wollycms",
      class="text-amber-400">"fields": {
        class="text-amber-400">"author": class="text-amber-400">"Chad",
        class="text-amber-400">"date": class="text-amber-400">"2026-03-20",
        class="text-amber-400">"featured": true
      },
      class="text-amber-400">"regions": {
        class="text-amber-400">"hero": [{ class="text-amber-400">"block_type": class="text-amber-400">"hero", ... }],
        class="text-amber-400">"content": [{ class="text-amber-400">"block_type": class="text-amber-400">"rich_text", ... }]
      }
    }
  ]
}
WollyCMS content types configuration showing custom page type definitions with fields and regions
Define page types with custom fields, regions, and block restrictions
Get Started