Convert markdown to JSX with ease for React and React-like projects.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Helper functions for content sanitization, slug generation, and other common markdown processing tasks.
Built-in sanitizer function for securing URLs and content against XSS and other security vulnerabilities.
/**
* Default sanitizer function for URLs and attribute values
* @param input - The input string to sanitize
* @returns Sanitized string or null if blocked
*/
function sanitizer(input: string): string | null;
/**
* Custom sanitizer function type for advanced security controls
* @param value - The attribute value to sanitize
* @param tag - The HTML tag containing the attribute
* @param attribute - The attribute name being sanitized
* @returns Sanitized value or null to remove the attribute
*/
type SanitizerFunction = (
value: string,
tag: HTMLTags,
attribute: string
) => string | null;Usage Examples:
import { sanitizer } from "markdown-to-jsx";
// Basic sanitization
const safeUrl = sanitizer("https://example.com"); // "https://example.com"
const blockedJs = sanitizer("javascript:alert('xss')"); // null
const blockedVbs = sanitizer("vbscript:msgbox('xss')"); // null
const blockedData = sanitizer("data:text/html,<script>"); // null
// Safe data URLs are allowed
const safeImage = sanitizer("data:image/png;base64,iVBOR..."); // allowed
// Custom sanitizer implementation
const strictSanitizer = (value, tag, attribute) => {
// Block all external URLs
if (attribute === 'href' || attribute === 'src') {
if (value.startsWith('http://') || value.startsWith('https://')) {
return null; // Block external resources
}
}
// Use default sanitizer for other cases
return sanitizer(value);
};
// Apply custom sanitizer
const options = {
sanitizer: strictSanitizer
};
const result = compiler(markdownWithLinks, options);Convert text strings to URL-safe slugs for heading IDs and anchor links.
/**
* Convert string to URL-safe slug for heading IDs
* @param str - Input string to convert to slug
* @returns URL-safe slug string
*/
function slugify(str: string): string;
/**
* Custom slug generation function type
* @param input - Input string to convert
* @param defaultFn - Default slugify function to fall back to
* @returns Custom slug string
*/
type SlugifyFunction = (
input: string,
defaultFn: (input: string) => string
) => string;Usage Examples:
import { slugify } from "markdown-to-jsx";
// Basic slug generation
slugify("Hello World"); // "hello-world"
slugify("Special Characters!@#"); // "special-characters"
slugify("Àccented Tëxt"); // "accented-text"
slugify("Multiple Spaces"); // "multiple-spaces"
slugify("123 Numbers"); // "123-numbers"
// Custom slugify function
const customSlugify = (input, defaultFn) => {
// Add timestamp to make unique
const baseSlug = defaultFn(input);
return `${baseSlug}-${Date.now()}`;
};
// Custom slugify with prefix
const prefixedSlugify = (input, defaultFn) => {
const baseSlug = defaultFn(input);
return `section-${baseSlug}`;
};
// Apply custom slugify
const options = {
slugify: customSlugify
};
const markdownWithHeadings = `
# Main Title
## Sub Title
### Another Heading
`;
const result = compiler(markdownWithHeadings, options);
// Generates unique IDs: main-title-1634567890123, etc.Configure sanitization behavior through the options system for comprehensive security control.
Usage Examples:
// Disable sanitization (not recommended for untrusted content)
const unsafeOptions = {
sanitizer: (value) => value // Pass through all values
};
// Strict sanitization
const strictOptions = {
sanitizer: (value, tag, attribute) => {
// Only allow specific domains
const allowedDomains = ['example.com', 'trusted-site.org'];
if (attribute === 'href' || attribute === 'src') {
try {
const url = new URL(value);
if (!allowedDomains.includes(url.hostname)) {
return null;
}
} catch {
// Invalid URL, allow relative links
if (!value.startsWith('/') && !value.startsWith('#')) {
return null;
}
}
}
// Use default sanitizer for validation
return sanitizer(value);
}
};
// Content-Security-Policy aware sanitizer
const cspSanitizer = (value, tag, attribute) => {
// Remove inline styles to comply with CSP
if (attribute === 'style') {
return null;
}
// Only allow relative URLs for images
if (tag === 'img' && attribute === 'src') {
if (!value.startsWith('/') && !value.startsWith('./')) {
return null;
}
}
return sanitizer(value);
};Complex utility function combinations for sophisticated markdown processing.
Usage Examples:
// Utility function factory
const createSecureProcessor = (config) => {
const customSanitizer = (value, tag, attribute) => {
// Apply domain whitelist
if (config.allowedDomains && (attribute === 'href' || attribute === 'src')) {
try {
const url = new URL(value);
if (!config.allowedDomains.includes(url.hostname)) {
return config.blockExternal ? null : '#blocked';
}
} catch {
// Not a full URL, allow if relative
}
}
return sanitizer(value);
};
const customSlugify = (input, defaultFn) => {
const baseSlug = defaultFn(input);
return config.slugPrefix ? `${config.slugPrefix}-${baseSlug}` : baseSlug;
};
return {
sanitizer: customSanitizer,
slugify: customSlugify
};
};
// Usage
const secureConfig = createSecureProcessor({
allowedDomains: ['example.com', 'cdn.example.com'],
blockExternal: true,
slugPrefix: 'doc'
});
const options = {
...secureConfig,
enforceAtxHeadings: true,
disableAutoLink: false
};
// Debugging utilities
const debugSanitizer = (value, tag, attribute) => {
console.log('Sanitizing:', { value, tag, attribute });
const result = sanitizer(value);
console.log('Result:', result);
return result;
};
const debugSlugify = (input, defaultFn) => {
console.log('Slugifying:', input);
const result = defaultFn(input);
console.log('Slug result:', result);
return result;
};
// Performance monitoring utilities
const performanceSanitizer = (() => {
let callCount = 0;
let totalTime = 0;
return (value, tag, attribute) => {
const start = performance.now();
const result = sanitizer(value);
const end = performance.now();
callCount++;
totalTime += (end - start);
if (callCount % 100 === 0) {
console.log(`Sanitizer performance: ${callCount} calls, ${totalTime.toFixed(2)}ms total`);
}
return result;
};
})();Guidelines and patterns for secure markdown processing with the utility functions.
Usage Examples:
// Secure configuration for user-generated content
const userContentOptions = {
// Use strict sanitization
sanitizer: (value, tag, attribute) => {
// Block all JavaScript
if (value.toLowerCase().includes('javascript:')) {
return null;
}
// Block data URLs except images
if (value.startsWith('data:') && !value.startsWith('data:image/')) {
return null;
}
// Use default sanitizer
return sanitizer(value);
},
// Disable HTML parsing for safety
disableParsingRawHTML: true,
// Use predictable slugs
slugify: (input, defaultFn) => {
// Remove potentially problematic characters
const cleaned = input.replace(/[<>]/g, '');
return defaultFn(cleaned);
}
};
// Configuration for trusted content
const trustedContentOptions = {
// Standard sanitization
sanitizer: sanitizer,
// Allow HTML parsing
disableParsingRawHTML: false,
// Enhanced slugs with metadata
slugify: (input, defaultFn) => {
const baseSlug = defaultFn(input);
// Add section prefix for navigation
return `section-${baseSlug}`;
}
};
// Apply based on content source
const processMarkdown = (content, isTrusted = false) => {
const options = isTrusted ? trustedContentOptions : userContentOptions;
return compiler(content, options);
};