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 toFIGMA_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