Implement Markdown Directives for Component Rendering

Summary

Successfully implemented a comprehensive markdown directive system that enables MDX-like component rendering using extended markdown syntax, starting with Figma embeds and establishing patterns for future directive types.

Why Care

This implementation brings powerful component embedding capabilities to our markdown content without requiring MDX files. Content authors can now embed interactive components like Figma designs directly in markdown using simple directive syntax, improving content richness while maintaining markdown portability. The established patterns make it easy to add new directive types for other services like Miro, Notion, or YouTube.

Implementation

Changes Made

  • Installed custom fork of remark-directive: pnpm add https://github.com/lossless-group/remark-directive.git
  • Created directive mapping and processing logic in /src/utils/markdown/remark-directives.ts
  • Updated Astro configuration in /astro.config.mjs to include directive plugins
  • Modified markdown processing pipeline across multiple layout files
  • Created new Figma embed component with advanced features
  • Updated AstroMarkdown renderer to handle directive nodes

File Tree of Changes

text
site/
├── astro.config.mjs (modified)
├── src/
│   ├── utils/
│   │   └── markdown/
│   │       └── remark-directives.ts (new)
│   ├── layouts/
│   │   └── OneArticle.astro (modified)
│   ├── components/
│   │   ├── articles/
│   │   │   └── OneArticleOnPage.astro (modified)
│   │   ├── markdown/
│   │   │   └── AstroMarkdown.astro (modified)
│   │   └── Figma-Object--Display.astro (new)
│   └── generated-content/
│       └── lost-in-public/
│           └── blueprints/
│               └── Maintain-Directives-in-Extended-Markdown-Render-Pipeline.md (updated)

Technical Details

Remark Plugin Configuration

In astro.config.mjs:
javascript
import remarkDirective from 'remark-directive';
import { directiveComponentMap, remarkDirectiveToComponent } from './src/utils/markdown/remark-directives.ts';

// In markdown config:
remarkPlugins: [
  /** @type {any} */ (remarkDirective), // Parse directive syntax
  /** @type {any} */ (remarkDirectiveToComponent), // Preserve directive nodes
],

Directive Mapping System

In /src/utils/markdown/remark-directives.ts:
typescript
export const directiveComponentMap: Record<string, string> = {
  'figma-embed': 'Figma-Object--Display.astro',
  // Future: 'miro-board': 'Miro-Board--Embed.astro',
};

export function remarkDirectiveToComponent() {
  return (tree: any) => {
    visit(tree, (node: any) => {
      if (node.type === 'leafDirective' || node.type === 'containerDirective') {
        // Preserve directive nodes for AstroMarkdown.astro to handle
      }
    });
  };
}

Directive Rendering in AstroMarkdown

In /src/components/markdown/AstroMarkdown.astro (lines 1264-1354):
typescript
{(node.type === "leafDirective" || node.type === "containerDirective") && (() => {
  const directiveName = node.name;
  const props = node.attributes || {};
  
  if (directiveName === 'figma-embed') {
    // Render Figma embed with iframe
    return (
      <div class="figma-embed-container" data-directive="figma-embed">
        <iframe src={embedUrl} ... />
      </div>
    );
  }
})}

Advanced Figma Component Features

The Figma-Object--Display.astro component includes:
  • Smart URL parsing to extract file ID and node ID
  • Figma API integration for metadata fetching
  • Automatic dimension calculation based on frame aspect ratios
  • Intelligent embed parameter defaults
  • User-specific authentication token support

Integration Points

  • Markdown Processing Pipeline: Directives flow through remarkDirective → remarkDirectiveToComponent → OneArticle → OneArticleOnPage → AstroMarkdown → Component
  • Layout Hierarchy: Content is processed in OneArticle.astro, passed to OneArticleOnPage.astro, and rendered by AstroMarkdown.astro
  • Authentication: Environment variables support pattern FIGMA_{USER}_TOKEN with fallback to FIGMA_EMBED_USER_TOKEN
  • Future Extensions: Component mapping pattern established for easy addition of new directive types

Documentation

  • Blueprint: /src/generated-content/lost-in-public/blueprints/Maintain-Directives-in-Extended-Markdown-Render-Pipeline.md - Comprehensive technical documentation with architecture diagrams
  • Usage Example:
    markdown
    ::figma-embed{
      src="https://www.figma.com/design/abc123/My-Design"
      width="800"
      height="600"
    }
  • Supported Syntax: Both leaf directives (::name{props}) and container directives (:::name ... :::)
  • Error Handling: Unknown directives display debug information in development mode