Remark Plugin

remark-codegloss is a unified remark plugin that transforms annotated fenced code blocks into CodeGloss instances at build time.

It supports two output modes:

  • mdx (default) — emits <CodeGloss /> MDX JSX. Use with MDX pipelines: @next/mdx, next-mdx-remote, Velite, Docusaurus.
  • html — emits a raw <code-gloss> HTML node with the config in a <script type="application/json"> child. Use with plain markdown pipelines (remark-rehyperehype-stringify) or anywhere outside of MDX.

How it works

The plugin walks the markdown AST looking for a specific pattern:

  1. A fenced code block with codegloss in its metadata
  2. Optionally followed by a json annotations code block

When it finds a match, it:

  • Replaces both blocks with a single CodeGloss node (JSX or HTML, depending on output mode)
  • Parses the annotations JSON and forwards its top-level keys (annotations, connections, arcs, callouts) as individual props — each key becomes its own prop on the emitted node, not merged
  • In mdx mode, auto-injects import { CodeGloss } from '@codegloss/react' (skippable via skipImport)

Detection pattern

The code block metadata must match this format:

  • lang (required) — the language identifier (js, ts, py, css, etc.)
  • codegloss (required) — the keyword that triggers detection
  • filename (optional) — displayed in the toolbar

Annotations block

The annotations block must immediately follow the codegloss block:

Four top-level keys are recognized:

  • annotations — array of Annotation objects. Each annotation can set "popover": true to switch its callout from inline-expanding to floating-popover presentation, and "defaultOpen": true to pre-open it on first render.
  • connections — array of Connection objects. Each connection can set "side": "right" to render on the right side of the block instead of in the left gutter, and "defaultOpen": true to pre-open its popover on first render.
  • arcs — arc-style overrides forwarded verbatim as a prop. Most commonly used for "arrowhead": true to turn on arrowheads at the to endpoint. See Arc style options for the full field list.
  • callouts — block-level callout behavior overrides. Set "popover": true to make every annotation in the block open as a floating popover. See Callout options.

See Pre-opening callouts for the full rules around defaultOpen — at most one annotation + one connection, last-wins cascade when multiple are marked.

If no annotations block follows, the component renders the code without annotations.

Options

Applying a global theme

Pass a theme option to apply a default theme to all code blocks processed by the plugin:

Individual code blocks can override the global default — the remark plugin only injects the theme when the block doesn't specify its own.

Treating every fence as a codegloss block

By default the plugin only transforms fences marked with the codegloss keyword (\``ts codegloss filename). A plain ```tsfence on the same page is left untouched, so it won't pick up the plugin'stheme/styleOverrides/highlight` defaults — meaning annotated and un-annotated blocks on the same MDX page can render with mismatched chrome.

Flip transformAllCodeFences: true to make every langed fence a <CodeGloss /> instance and inherit the same defaults:

The <lang> codegloss [filename] form still wins for any block that needs paired annotations — this option just removes the marker requirement for un-annotated blocks. Fences with no language and orphan json annotations blocks are skipped even when this is on.

Configuration examples

MDX mode (default)

Next.js with @next/mdx

Docusaurus

skipImport: true is recommended in Docusaurus because the component is provided via the swizzled MDX components map (see the Docusaurus setup guide).

Non-React MDX (Vue, Preact)

The auto-injected import targets @codegloss/react, which matches the dominant @mdx-js/react consumers (Next.js, Docusaurus, Velite, Astro's MDX integration). If you're using @mdx-js/vue or @mdx-js/preact, set skipImport: true and provide CodeGloss via your MDX components mapping — point it at @codegloss/vue or your own wrapper:

For SvelteKit (mdsvex) and VitePress, prefer output: 'html' instead — it emits a raw <code-gloss> element with no import at all.

Generic MDX pipeline

HTML mode (plain markdown)

For pipelines that produce plain HTML (no JSX, no React):

The output is a raw <code-gloss> element with the config in a <script type="application/json"> child:

You're responsible for loading the codegloss runtime in your HTML page so the custom element gets registered:

This pattern works with marked, markdown-it, and any static site generator that goes through remark.

Edge cases

  • Invalid JSON — if the annotations block contains malformed JSON, the plugin logs a warning and renders the code block without annotations
  • Missing annotations block — the codegloss block renders as a CodeGloss instance with just the code, no annotations
  • Duplicate imports — in mdx mode, the plugin checks for existing CodeGloss imports before injecting one
  • Nested blocks — the plugin traverses child nodes recursively, so codegloss blocks inside blockquotes or other containers are detected
  • Script tag escaping — in html mode, the JSON payload escapes </script sequences to prevent breaking out of the script tag