Gatsby transformer plugin for Markdown using the Remark library and ecosystem
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Comprehensive plugin options schema with validation for controlling markdown processing, sub-plugin integration, and security settings.
Defines and validates all plugin configuration options using Joi schema validation.
/**
* Defines plugin options schema for validation
* @param context - Plugin schema context
* @param context.Joi - Joi validation library instance
* @returns Joi schema object for plugin options validation
*/
function pluginOptionsSchema({ Joi }): Joi.Schema;Usage Example:
This function is automatically called by Gatsby to validate plugin configuration in gatsby-config.js.
Controls activation of the remark-footnotes plugin for footnote processing.
/**
* Activates Footnotes mode
* @default true
*/
footnotes: boolean;Usage Example:
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
footnotes: true, // Enable footnotes processing
},
},
],
}Footnote Markdown Syntax:
Here is a footnote reference[^1].
[^1]: This is the footnote content.Controls activation of the remark-gfm plugin for GitHub-style markdown features.
/**
* Activates GitHub Flavored Markdown mode
* @default true
*/
gfm: boolean;GFM Features Enabled:
~~deleted text~~- [x] completed taskUsage Example:
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
gfm: true, // Enable GitHub Flavored Markdown
},
},
],
}Defines HTML tag used as excerpt separator instead of pruneLength-based excerpts.
/**
* HTML tag to use as excerpt separator
* If your Markdown file contains HTML, excerpt will not return a value unless this is set
*/
excerpt_separator?: string;Usage Example:
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
excerpt_separator: `<!-- endexcerpt -->`,
},
},
],
}Markdown with Excerpt Separator:
---
title: "My Post"
---
This content will be included in the excerpt.
<!-- endexcerpt -->
This content will NOT be included in the excerpt.Array of gatsby-remark-* plugins to process markdown content.
/**
* List of remark plugins with their configurations
* See: https://github.com/gatsbyjs/gatsby/tree/master/examples/using-remark
*/
plugins: Array<PluginConfig>;
interface PluginConfig {
resolve: string;
options?: Record<string, any>;
}Usage Example:
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
// Simple plugin without options
`gatsby-remark-copy-linked-files`,
// Plugin with configuration
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 756,
quality: 90,
},
},
// Plugin with complex configuration
{
resolve: `gatsby-remark-prismjs`,
options: {
classPrefix: "language-",
inlineCodeMarker: null,
showLineNumbers: true,
},
},
],
},
},
],
}Controls whether JavaScript engines are enabled for gray-matter frontmatter processing.
/**
* Enable JS for gray-matter frontmatter parsing
* @default false
* @security This can cause security risks - use with caution
*/
jsFrontmatterEngine: boolean;Security Warning: Enabling this option allows execution of JavaScript code in frontmatter, which can pose security risks. Only enable if you control all markdown content and require this functionality.
Usage Example:
// gatsby-config.js - NOT RECOMMENDED
module.exports = {
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
jsFrontmatterEngine: true, // Security risk - avoid unless necessary
},
},
],
}JavaScript Frontmatter Example:
---js
{
title: "Generated Title",
date: new Date().toISOString(),
tags: ["tag1", "tag2"].map(tag => tag.toUpperCase())
}
---
# Content hereCustom block types for remark parsing (used internally by remark).
/**
* Custom block types for remark parsing
*/
blocks?: string[];Usage Example:
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
blocks: ["custom-block"], // Custom block types
},
},
],
}Default configuration for table of contents generation.
/**
* Default options for table of contents generation
*/
tableOfContents?: {
/**
* Start ToC from this heading onwards
* @default null
*/
heading?: string | null;
/**
* Maximum depth of headings to include
* @default 6
*/
maxDepth?: number;
};Usage Example:
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
tableOfContents: {
heading: "Contents", // Skip headings until "Contents" is found
maxDepth: 3, // Only include h1, h2, h3
},
},
},
],
}The plugin includes custom validation logic for security and compatibility:
/**
* Custom validation that warns about JavaScript frontmatter security risks
* and provides fallback stubs for JS/JavaScript engines when disabled
*/
.custom(value => {
const { jsFrontmatterEngine, engines = {} } = value || {};
if (jsFrontmatterEngine) {
// Show security warning
console.warn("JS frontmatter engine security warning...");
return value;
}
// Provide stub engines to prevent execution
const js = () => {
console.warn("JS frontmatter detected but disabled for security...");
return {}; // Return empty frontmatter
};
return {
...value,
engines: {
...engines,
js,
javascript: js,
},
};
});This validation ensures that JavaScript frontmatter is safely handled even when accidentally used, preventing security vulnerabilities while providing clear warnings to developers.
// gatsby-config.js - Complete configuration example
module.exports = {
plugins: [
`gatsby-source-filesystem`, // Required for file processing
{
resolve: `gatsby-transformer-remark`,
options: {
// Remark processing options
footnotes: true,
gfm: true,
excerpt_separator: `<!-- endexcerpt -->`,
// Custom block types (advanced usage)
blocks: [],
// Security option (keep disabled)
jsFrontmatterEngine: false,
// Table of contents defaults
tableOfContents: {
heading: null,
maxDepth: 6,
},
// Sub-plugin ecosystem
plugins: [
// File handling
`gatsby-remark-copy-linked-files`,
// Image processing
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 1200,
quality: 90,
withWebp: true,
},
},
// Syntax highlighting
{
resolve: `gatsby-remark-prismjs`,
options: {
classPrefix: "language-",
inlineCodeMarker: null,
showLineNumbers: true,
noInlineHighlight: false,
},
},
// External links
{
resolve: `gatsby-remark-external-links`,
options: {
target: "_blank",
rel: "noopener noreferrer",
},
},
],
},
},
],
}