Shortcodes
Shortcodes allow embedding interactive components within CMS content. They use a WordPress-like
syntax and are parsed when content is rendered through the HtmlRenderer component.
The registry lives in lib/shortcodes/parser.ts (SHORTCODE_DEFINITIONS),
and the React mapping is in components/shortcodes/index.tsx (ShortcodeRenderer).
Syntax
| Type | Syntax | Example |
|---|---|---|
| Self-closing | [name attr="value"] |
[youtube id="dQw4w9WgXcQ"] |
| With content | [name]content[/name] |
[callout]Note text[/callout] |
| Simple | [name] |
[divider] |
Available Shortcodes
Media
Video embeds for YouTube and Vimeo. Both are responsive (16:9 aspect ratio), lazy-loaded, and styled with rounded corners and shadows.
[youtube id="dQw4w9WgXcQ"]
[vimeo id="76979871"]Callouts
Styled callout boxes with four variants. Each type has its own color scheme and icon (Info, Warning triangle, Check circle, X circle).
[callout type="info"]Informational content[/callout]
[callout type="warning"]Warning content[/callout]
[callout type="success"]Success content[/callout]
[callout type="error"]Error content[/callout]An optional title attribute renders a heading above the body: [callout type="info" title="Note"]Body[/callout].
Layout
Layout helpers for separating and spacing content blocks.
[divider]
[spacer size="lg"][divider] inserts a styled horizontal separator. [spacer] inserts vertical spacing; size accepts sm, md (default), lg, or xl.
Interactive & Content Blocks
Buttons, collapsible accordions, themed cards, and inline highlighted text.
[button href="/pricing" variant="default"]Get started[/button]
[accordion title="Click to expand"]Hidden content here[/accordion]
[card title="Feature" icon="star"]Card content[/card]
[highlight color="yellow"]Important text[/highlight][button]: href is required (internal path or external URL); variant accepts default, outline, ghost, or destructive; optional size is sm, default, or lg.
[accordion]: title is required; body content is the collapsible payload.
[card]: optional title and icon (info, star, check, warning).
[highlight]: optional color (yellow default, green, blue, pink).
Parser Implementation
The shortcode parser in lib/shortcodes/parser.ts scans HTML content for shortcode patterns and replaces them with the corresponding React components. Self-closing forms (e.g. [youtube id="abc"]) and paired forms (e.g. [button href="/signup"]Sign Up[/button]) are both supported. The canonical attribute on [button] is href — not url.
HTML Renderer
The HtmlRenderer component safely renders CMS content by sanitizing HTML through DOMPurify, then processing any shortcodes into React components. It supports markdown rendering with syntax highlighting for blog posts and code-containing pages.
Shortcode Components
Shortcode components are defined in components/shortcodes/index.tsx. Each shortcode maps to a React component that renders the appropriate UI. Built-in shortcodes include media embeds (YouTube, Vimeo), callouts, buttons, layout helpers (divider, spacer), and content blocks (accordion, card, highlight). To add a custom shortcode, create a new component and register it in the ShortcodeRenderer switch.
Adding New Shortcodes
- Create the React component that renders the shortcode's UI (server component unless it needs interactivity).
- Register it in the
ShortcodeRendererswitch incomponents/shortcodes/index.tsxunder a unique tag name. - Add the definition to
SHORTCODE_DEFINITIONSinlib/shortcodes/parser.ts; if it is a paired shortcode (with body content), also add the tag name toPAIRED_SHORTCODES. - Authors can now use
[your-tag attr="value"]inside any CMS page or blog post body.