Skip to main content

Directives Plugin

The directives plugin adds support for markdown directives, enabling you to create callouts, admonitions, and custom containers in your documentation.

Features

  • Container Directives - Multi-line content blocks
  • Callout Support - Tip, note, warning, caution, danger, info
  • Details/Summary - Collapsible content sections
  • Custom Directives - Extensible for custom use cases

Configuration

The plugin is automatically enabled:
packages/doom/src/plugins/directives/index.ts:6-13
export const directivesPlugin = (): RspressPlugin => {
  return {
    name: 'doom-directives',
    markdown: {
      remarkPlugins: [remarkDirective, remarkDirectives],
    },
  }
}

Supported Directives

Callouts

Create attention-grabbing callout boxes:
:::tip
This is a helpful tip for your users.
:::

:::note
Important information to remember.
:::

:::warning
Be careful with this operation.
:::

:::caution
Proceeds with caution in production.
:::

:::danger
This action is dangerous and irreversible.
:::

:::info
Additional context or background information.
:::

Rendered Output

:::tip This is a helpful tip for your users. ::: :::warning Be careful with this operation. ::: :::danger This action is dangerous and irreversible. :::

Custom Titles

You can customize the title of any callout:
:::tip[Pro Tip]
Use keyboard shortcuts to work faster.
:::

:::warning[⚠️ Breaking Change]
This feature will be removed in v2.0.
:::

Details/Summary

Create collapsible content sections:
:::details[Click to expand]
This content is hidden by default and can be expanded by clicking.

You can include:
- Multiple paragraphs
- Code blocks
- Any markdown content
:::
:::details[Click to expand] This content is hidden by default and can be expanded by clicking. You can include:
  • Multiple paragraphs
  • Code blocks
  • Any markdown content :::

Callouts Container

Group multiple callouts together:
:::callouts
- First callout item
- Second callout item
- Third callout item
:::

Implementation

The plugin processes directives using the remark-directive library:
packages/doom/src/plugins/directives/remark-directives.ts:6-15
const CONTAINER_DIRECTIVE_TYPES = new Set([
  'tip',
  'note',
  'warning',
  'caution',
  'danger',
  'info',
  'details',
  '$$$callout$$$',
])

Processing Logic

The plugin:
  1. Visits all directive nodes in the markdown AST
  2. Checks if the directive is a recognized container type
  3. Applies appropriate styling and classes
  4. Converts unrecognized directives back to text
packages/doom/src/plugins/directives/remark-directives.ts:17-35
export const remarkDirectives: Plugin<[], Root> = function () {
  return (root) => {
    visit(root, (node, index, parent) => {
      if (
        node.type !== 'containerDirective' &&
        node.type !== 'leafDirective' &&
        node.type !== 'textDirective'
      ) {
        return
      }

      const data = node.data || (node.data = {})

      if (
        node.type === 'containerDirective' &&
        CONTAINER_DIRECTIVE_TYPES.has(node.name)
      ) {
        return
      }
      // ... handle special cases
    })
  }
}

Directive Types

Markdown directives come in three types:

Container Directives

Multi-line content blocks:
:::directive-name[optional title]
content
:::

Leaf Directives

Single-line blocks:
::directive-name[optional content]

Text Directives

Inline content:
Some text :directive-name[content] more text.

Styling

Callouts receive automatic styling through Doom’s global styles. You can customize them:
.doom-callout {
  &.tip {
    border-color: var(--color-success);
  }
  
  &.warning {
    border-color: var(--color-warning);
  }
  
  &.danger {
    border-color: var(--color-danger);
  }
}

Creating Custom Directives

To add custom directive support:
  1. Fork the directives plugin
  2. Add your directive name to the recognized types
  3. Implement custom handling logic
const CONTAINER_DIRECTIVE_TYPES = new Set([
  'tip',
  'note',
  'warning',
  // Add your custom directive
  'custom-directive',
])

// In the visitor:
switch (node.name) {
  case 'custom-directive': {
    data.hProperties = { className: 'my-custom-directive' }
    break
  }
}

Best Practices

  1. Use Semantic Types - Choose the right callout type for your message
  2. Custom Titles - Make titles descriptive and actionable
  3. Don’t Overuse - Too many callouts reduce their impact
  4. Consistent Style - Use similar callout types across your docs
  5. Accessible Content - Ensure callout content is readable

Examples

Installation Warning

:::warning[Prerequisites Required]
Before installing, ensure you have Node.js 20+ installed.

Check your version:
\`\`\`bash
node --version
\`\`\`
:::

Feature Tip

:::tip[Performance Optimization]
Enable lazy loading to improve initial page load times:

\`\`\`typescript
export default defineConfig({
  lazy: true
})
\`\`\`
:::

Breaking Change

:::danger[Breaking Change in v2.0]
The `oldFunction()` API will be removed. Migrate to `newFunction()`:

\`\`\`typescript
// Before (deprecated)
oldFunction({ option: true })

// After (recommended)
newFunction({ option: true })
\`\`\`
:::

Integration with Shiki

Directives work seamlessly with code highlighting using Shiki transformers for callouts within code blocks.

Build docs developers (and LLMs) love