• English
  • Rehype plugins

    Rehype plugins post-process HAST, the HTML syntax tree produced from Markdown. Use them to change element properties or normalize HTML before rendering.

    Declare a plugin

    This plugin uses image descriptions as hover titles:

    pnpm add @fluxdown/core-presets
    pnpm add -D @types/hast unified
    import type { Root, RootContent } from 'hast';
    import type { Plugin } from 'unified';
    
    import { BaseRehypePlugin } from '@fluxdown/core-presets/rehype';
    
    class ImageTitlesPlugin extends BaseRehypePlugin {
      static readonly key = 'rehype-image-titles';
    
      readonly plugin: Plugin<[], Root> = () => (tree) => {
        function visit(node: Root | RootContent) {
          if (node.type === 'element' && node.tagName === 'img') {
            const { alt, title } = node.properties;
    
            if (typeof alt === 'string' && !title) {
              node.properties.title = alt;
            }
          }
    
          if ('children' in node) {
            node.children.forEach(visit);
          }
        }
    
        visit(tree);
      };
    }
    
    const rehypes = [ImageTitlesPlugin];

    Add rehypes to the Core inputs from the quick start. The transform runs again when a content block is recompiled.

    The default sanitizer still processes the output. Properties and tags added by a plugin must be allowed by its schema.

    Allow additional HTML tags

    Embedded HTML passes through both syntax filtering and HAST sanitization. Configure both stages to allow an extra tag, such as mark:

    import { toClosure } from 'stative';
    
    const remarks = toClosure<RemarkConfigs>({
      'remark-syntax-html-allowed': {
        enabledTags: ['mark'],
      },
    });
    
    const rehypes = toClosure<RehypeConfigs>({
      'rehype-sanitizer': {
        allowedTags: ['mark'],
      },
    });

    toClosure turns each configuration object into a readable Core input. Pass both remarks and rehypes to Core. These options extend the existing tag lists. Use the sanitizer's fallback schema to allow additional attributes.

    Pass options with a plugin class

    You can express the same configuration as [PluginClass, options]. Core passes the options to the constructor and manages the instance:

    import type { IPluggable, IRehypePlugin, IRemarkPlugin } from '@fluxdown/types';
    
    import { SanitizerRehypePlugin } from '@fluxdown/core-presets/rehype';
    import { SyntaxHtmlAllowedRemarkPlugin } from '@fluxdown/core-presets/remark';
    
    type RemarkPlugin = IPluggable<IRemarkPlugin, unknown>;
    type RehypePlugin = IPluggable<IRehypePlugin, unknown>;
    
    const remarks: RemarkPlugin[] = [
      [SyntaxHtmlAllowedRemarkPlugin, { enabledTags: ['mark'] }],
    ];
    
    const rehypes: RehypePlugin[] = [
      [SanitizerRehypePlugin, { allowedTags: ['mark'] }],
    ];

    Choose keyed options to keep built-in configuration together, or class tuples to register and configure plugins in one place. Pass the class; Core creates the instance.

    Built-in plugins

    Core includes these plugins by default; no registration is needed.

    PRESET_REHYPE_PLUGINS, exported from @fluxdown/core-presets/rehype.

    PluginPurpose
    RawParserRehypePluginParses allowed raw HTML into HAST nodes alongside Markdown-generated content.
    SanitizerRehypePluginCleans HTML output according to allowed tags, attributes, and protocols.

    These stages work together to handle HTML embedded in Markdown. See Allow additional HTML tags for an example.