n8n-nodes-any-notion-block-convertor
v1.1.0
Published
Universal n8n node for converting between any Notion block types, comments, properties, and multiple output formats
Maintainers
Readme
n8n-nodes-any-notion-block-convertor
A universal n8n node for converting between any Notion block types, comments, properties, and multiple output formats. Supports bidirectional conversion with perfect formatting preservation.
Note: Version 1.1.0 includes important node renaming to resolve installation conflicts. See upgrade instructions below.
🚀 Features
Universal Conversion Types
- Comment Processing: Convert Notion comments to any format (Markdown, HTML, Blocks, Properties)
- Database Properties: Convert database rich text with automatic property labeling
- Page Blocks: Handle full page content with unlimited nesting depth
- Markdown Processing: Convert markdown to Notion-ready JSON structures
- Direct Conversion: Comment → Blocks/Properties without markdown mediation
Multiple Output Formats
- JSON: Ready for Notion API requests (PATCH/POST endpoints)
- Markdown: Standard markdown with full formatting support
- HTML: Semantic HTML markup for web integration
- GitHub Flavored Markdown (GFM): Enhanced markdown with GitHub features
- MDX: Markdown with JSX components for React applications
Advanced Features
- Bidirectional Conversion: Perfect round-trip Notion ↔ Markdown ↔ Notion
- Direct Conversion: Skip markdown step for perfect formatting preservation
- Colored Text Handling: Configurable conversion of Notion's color backgrounds
- Deep Nesting Support: Unlimited nesting with optional depth controls
- Performance Optimized: Efficient processing with caching and metadata tracking
- API Ready: Output formats designed for direct Notion API integration
📦 Installation
Through n8n Community Nodes (Recommended)
- Go to Settings → Community Nodes in your n8n instance
- Click Install a community node
- Enter:
n8n-nodes-any-notion-block-convertor - Click Install
Manual Installation
npm install n8n-nodes-any-notion-block-convertor🔄 Upgrading from Previous Versions
Important: If you previously installed any version of this package with a different name (e.g., n8n-nodes-notion-to-markdown), you must uninstall the old version first to avoid conflicts.
Quick Upgrade Steps:
- Uninstall old version: Go to Settings → Community Nodes → Find old package → Uninstall
- Restart n8n
- Install new version: Follow installation steps above
For detailed upgrade instructions, see UNINSTALL_OLD_VERSION.md.
Why the upgrade is needed:
- Node internal identifiers changed from
notionToMarkdowntoanyNotionBlockConvertor - Node class name changed from
NotionToMarkdowntoAnyNotionBlockConvertor - Node display name changed from "Notion to Markdown" to "Any Notion Block Convertor"
🔧 Usage
- Add the "Any Notion Block Convertor" node to your n8n workflow
- Choose conversion type:
- Forward Conversion: Notion → Markdown/HTML (comment, database_property, page_blocks)
- Reverse Conversion: Markdown → Notion (markdown_to_rich_text, markdown_to_blocks)
- Direct Conversion: Comment → Notion (comment_to_blocks, comment_to_property)
- Set the input data property containing your content
- Choose output format (JSON, Markdown, HTML, etc.)
- Configure colored text handling and advanced options
- Run the workflow to convert between any Notion formats
⚠️ Important Configuration Notes
Input Data Property Field:
- Enter the property name that contains your data (e.g., "data", "json", "body")
- DO NOT enter expressions like
{{ $json.rich_text }}in this field - The node will automatically handle the data extraction from the specified property
Correct Examples:
- ✅
data(if your data is initems[0].json.data) - ✅
json(if your data is initems[0].json.json) - ✅
body(if your data is initems[0].json.body)
Incorrect Examples:
- ❌
{{ $json.rich_text }}(this is an expression, not a property name) - ❌
$json.data(this is an expression, not a property name)
Special Case: If you need to pass data directly via expressions, the node will automatically detect this and handle it appropriately.
📋 Conversion Types & Examples
1. Forward Conversion: Comment → Output
Process Notion comment objects with rich text formatting:
Input:
{
"rich_text": [
{
"type": "text",
"text": {"content": "This is "},
"annotations": {"bold": false, "italic": false, "color": "default"}
},
{
"type": "text",
"text": {"content": "formatted text"},
"annotations": {"bold": true, "italic": true, "color": "red_background"}
}
]
}Output (with underline colored text):
This is <u>***formatted text***</u>2. Forward Conversion: Database Property → Output
Convert database property fields with automatic labeling:
Input:
{
"properties": {
"Title": {
"type": "title",
"title": [{"type": "text", "text": {"content": "Task Title"}}]
},
"Description": {
"type": "rich_text",
"rich_text": [{"type": "text", "text": {"content": "Task description"}}]
}
}
}Output:
# Task Title
**Description:** Task description3. Forward Conversion: Page Blocks → Output
Process full Notion page content with nested structures:
Input:
{
"blocks": [
{
"type": "heading_1",
"heading_1": {
"rich_text": [{"type": "text", "text": {"content": "Main Section"}}]
}
},
{
"type": "paragraph",
"paragraph": {
"rich_text": [{"type": "text", "text": {"content": "Content paragraph"}}]
}
}
]
}Output:
# Main Section
Content paragraph4. Reverse Conversion: Markdown → Notion
Convert markdown back to Notion-ready JSON structures:
Input:
{
"markdown": "**Bold** text with `code` and *italic*"
}Output (JSON for API):
{
"rich_text": [
{
"type": "text",
"text": {"content": "Bold"},
"annotations": {"bold": true, "code": false}
},
{
"type": "text",
"text": {"content": " text with "},
"annotations": {"bold": false, "code": false}
},
{
"type": "text",
"text": {"content": "code"},
"annotations": {"bold": false, "code": true}
}
]
}5. Direct Conversion: Comment → Notion Structures
Skip markdown step for perfect formatting preservation:
Comment → Property (for database updates):
// Input: Comment rich_text array
// Output: Ready for PATCH /v1/pages/{page_id}
{
"properties": {
"Description": {
"type": "rich_text",
"rich_text": [/* exact comment formatting preserved */]
}
}
}Comment → Blocks (for page content):
// Input: Comment rich_text array
// Output: Ready for POST /v1/pages or page updates
{
"blocks": [
{
"type": "paragraph",
"paragraph": {
"rich_text": [/* exact comment formatting preserved */]
}
}
]
}⚙️ Configuration Options
Input Type
comment- Convert Notion comment to any output formatdatabase_property- Convert database fields to any formatpage_blocks- Convert page content with unlimited nestingmarkdown_to_rich_text- Convert markdown to Notion rich_text JSONmarkdown_to_blocks- Convert markdown to Notion blocks JSONcomment_to_blocks- Direct comment to blocks (no markdown step)comment_to_property- Direct comment to property (no markdown step)
Output Format
json- Notion API-ready JSON structuresmarkdown- Standard Markdowngfm- GitHub Flavored Markdownmdx- MDX (Markdown + JSX)html- Semantic HTML markup
Colored Text Handling
ignore- Skip colored backgrounds (default)underline- Convert to<u>tagsbold- Convert to**bold**underline_bold- Combine both treatments
Advanced Options
maxDepth- Limit nesting depth for page blocks (0 = unlimited)inputProperty- Source property name (default: "data")outputProperty- Target property name (default: "markdown")
🧪 Testing & Development
# Install dependencies
npm install
# Run tests
npm test
# Build the node
npm run build
# Run linting
npm run lint
# Development with auto-rebuild
npm run devTest Coverage
- ✅ Comment conversion with all formatting options
- ✅ Database property handling (single and multiple)
- ✅ Page blocks with notion-to-md integration
- ✅ All output formats (Markdown, GFM, MDX, HTML)
- ✅ Colored text handling variations
- ✅ Error handling and edge cases
- ✅ Performance benchmarks (1000+ elements, 70KB+ content)
- ✅ Edge case testing (15+ malformed data scenarios)
- ✅ Concurrent processing and memory leak testing
- ✅ Real-world data validation
📊 Sample Outputs
See SAMPLE_OUTPUT.md for detailed examples of conversion results with your actual comment data.
🏗️ Architecture
├── nodes/AnyNotionBlockConvertor/ # Main n8n node implementation
├── conversion/ # Conversion logic by input type
│ ├── comments.ts # Comment processing
│ ├── databaseProperties.ts # Database field processing
│ ├── pageBlocks.ts # Page content processing
│ ├── markdownToRichText.ts # Markdown → Rich Text conversion
│ ├── markdownToBlocks.ts # Markdown → Blocks conversion
│ ├── commentToBlocks.ts # Direct Comment → Blocks
│ └── commentToProperty.ts # Direct Comment → Property
├── utils/ # Shared utilities
│ ├── richTextFormatter.ts # Rich text to markdown conversion
│ └── formatConverter.ts # Output format conversion
└── types/ # TypeScript definitions🤝 Contributing
This node is built for defensive security use only. Contributions should focus on:
- Improving conversion accuracy
- Adding support for new Notion block types
- Performance optimizations
- Documentation enhancements
🙏 Attribution
This project incorporates and builds upon excellent open source work:
- notion-to-md (MIT License) - Core Notion block conversion engine by Souvik Kar Mahapatra
- n8n-nodes-notion-markdown (MIT License) - Architectural inspiration for n8n integration
Special thanks to the n8n community and Notion's public API documentation.
⚖️ Licensing & Legal
License
MIT License - see LICENSE file for complete terms.
Intellectual Property
- Original Implementation: All conversion logic, UI, validation, and advanced features are original implementations
- Dependencies: Uses only MIT-licensed and permissive open source dependencies
- Commercial Use: Fully permitted for commercial and enterprise use
- Patent Safety: No known patent conflicts for markdown conversion functionality
Compliance
This project complies with all applicable licenses and follows best practices for open source development. See LICENSING_ANALYSIS.md for detailed IP analysis.
Package Naming
✅ Updated: Package renamed to "n8n-nodes-any-notion-block-convertor" for better clarity and to address trademark considerations.
🐛 Troubleshooting
Common Issues
Error: "There is already an entry with this name"
- Cause: Previous version of this package is installed with old node identifiers
- Solution: Uninstall old version first, then install new version. See UNINSTALL_OLD_VERSION.md
- Fixed in: Version 1.1.0+ (node renamed to resolve conflicts)
Error: inputProperty.trim is not a function
- Cause: You entered an expression (like
{{ $json.rich_text }}) in the "Input Data Property" field instead of a property name - Solution: Enter the property name only (e.g., "data", "json", "body")
- Fixed in: Version 1.0.1+
Error: No data found in property 'X'
- Cause: The specified property doesn't exist in your input data
- Solution: Check available properties in your input data and update the property name
Error: Invalid comment data: Comment input must contain a "rich_text" array
- Cause: Your input data doesn't match the expected structure for the selected input type
- Solution: Verify your input type matches your data structure, or use the correct input type
📄 License
MIT License - see LICENSE file for details
