Skip to content

rehype Plugin

The @mrsf/rehype-mrsf package is a rehype plugin that renders Sidemark review comments directly into your HTML output. It works with the entire unified ecosystem — Astro, Next.js MDX, Docusaurus, and any other tool that uses remark/rehype.

Install

bash
npm install @mrsf/rehype-mrsf

Live Demo

The panel below renders a sample document with the rehype plugin. Hover the gutter badges or inline highlights to see tooltips, toggle options, and try the interactive actions.

Quick Start

ts
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import rehypeStringify from "rehype-stringify";
import { rehypeMrsf } from "@mrsf/rehype-mrsf";

const html = await unified()
  .use(remarkParse)
  .use(remarkRehype)
  .use(rehypeMrsf, { documentPath: "docs/guide.md" })
  .use(rehypeStringify, { allowDangerousHtml: true })
  .process(markdownSource);

Include the stylesheet:

ts
import "@mrsf/rehype-mrsf/style.css";

TIP

Pass { allowDangerousHtml: true } to rehype-stringify so the raw HTML tooltips render correctly.

Options

OptionTypeDefaultDescription
commentsMrsfDocumentPre-loaded sidecar data (highest priority)
loader() => MrsfDocument | nullCustom loader function
sidecarPathstringExplicit path to .review.yaml / .review.json
documentPathstringAuto-discover sidecar next to this markdown file
showResolvedbooleantrueShow resolved comments
interactivebooleanfalseShow action buttons (resolve, reply, edit)
gutterPosition'left' | 'right''right'Badge placement
gutterForInlinebooleantrueShow badge for inline-highlighted comments
inlineHighlightsbooleantrueHighlight selected_text with <mark>
lineHighlightbooleanfalseAdd background tint on commented lines
theme'light' | 'dark' | 'auto''auto'Color scheme hint
cwdstringprocess.cwd()Working directory for file discovery

Data Provisioning

The plugin supports four ways to load sidecar data, in priority order:

  1. comments — pre-loaded sidecar data (works everywhere, including browsers)
  2. loader — custom function (works everywhere)
  3. sidecarPath — explicit file path (Node.js only)
  4. documentPath — auto-discover .review.yaml/.json (Node.js only)

Gutter Placement

ts
// Left gutter — badge in a margin column
.use(rehypeMrsf, { comments, gutterPosition: "left" })

// Right — badge floated right (default)
.use(rehypeMrsf, { comments, gutterPosition: "right" })

For inline emphasis, use inlineHighlights and gutterForInline rather than a separate gutter mode.

Framework Integration

Astro

ts
// astro.config.mjs
import { rehypeMrsf } from "@mrsf/rehype-mrsf";

export default defineConfig({
  markdown: {
    rehypePlugins: [
      [rehypeMrsf, { documentPath: "src/content/guide.md" }],
    ],
  },
});

Next.js MDX

ts
// next.config.mjs
import createMDX from "@next/mdx";
import { rehypeMrsf } from "@mrsf/rehype-mrsf";

const withMDX = createMDX({
  options: {
    rehypePlugins: [
      [rehypeMrsf, { documentPath: "docs/guide.md" }],
    ],
  },
});

export default withMDX(nextConfig);

Interactive Mode

ts
.use(rehypeMrsf, { comments, interactive: true })

Hook into events with the controller (adds inline + gutter action buttons and built-in modals for add/reply/edit/resolve/unresolve/delete):

ts
import { refreshAll } from "@mrsf/rehype-mrsf/controller";

document.addEventListener("mrsf:submit", async (e) => {
  // Persist to your API; payload is snake_case and matches the CLI types
  // { action, commentId, text?, line?, end_line?, start_column?, end_column?, selection_text? }
  await saveComment(e.detail);
});

Events fired after user confirmation: mrsf:add, mrsf:reply, mrsf:edit, mrsf:resolve, mrsf:unresolve, mrsf:delete, mrsf:navigate, plus mrsf:submit (always includes the full payload). Set window.mrsfDisableBuiltinUi = true before loading the controller to opt out of the built-in dialogs and render your own.

For async renderers such as Mermaid, the controller auto-refreshes gutter positions when the rendered DOM changes. If you need an explicit refresh after a render pass, call refreshAll() once Mermaid has finished:

ts
await mermaid.run();
refreshAll();

CSS Customization

Override CSS custom properties to match your theme:

css
:root {
  --mrsf-badge-bg: #0969da;
  --mrsf-tooltip-bg: #1c1c1c;
  --mrsf-highlight-bg: rgba(255, 213, 79, 0.3);
  --mrsf-gutter-width: 50px;
}

Browser Usage

In browser environments, bundlers automatically resolve to a file-system-free entry point via the "browser" export condition:

ts
import { rehypeMrsf } from "@mrsf/rehype-mrsf"; // auto-resolves

Only comments and loader options work in the browser.

Comparison with markdown-it Plugin

Both @mrsf/rehype-mrsf and @mrsf/markdown-it-mrsf produce identical visual output — same CSS classes, same data attributes, same tooltips. Choose based on your toolchain:

rehypemarkdown-it
Ecosystemunified (remark/rehype)markdown-it
Used byAstro, Next.js MDX, DocusaurusVitePress, many Node.js tools
Architecturehast tree transformationToken stream injection
Package@mrsf/rehype-mrsf@mrsf/markdown-it-mrsf

Released under the MIT License.