Stringification
How Fumadocs turns your documents into Markdown.
Remark LLMs and Remark Structure output Markdown, for LLMs and search. Instead of stringifying the syntax tree, they slice your authored source:
- Markdown stays as you wrote it, nothing is escaped or reformatted.
- Remark plugins change it only by recording edits.
- It's fast, no syntax tree is serialized.
How It Works
The output is the source of your document, with the edits of plugins applied. Nodes are located by their position:
- A node with a
positionoutputs its source. - A node without one, like those inserted by plugins, outputs nothing. Its plugin defines its Markdown instead.
For example, Remark Image turns  into an <img> element, the output keeps .
Editing the Output
A plugin replacing authored content records the Markdown of its node with replaceSource():
import type { Root } from 'mdast';
import type { VFile } from 'vfile';
import { visit } from 'unist-util-visit';
import { replaceSource } from 'fumadocs-core/mdx-plugins/stringifier';
export function remarkNote() {
return (tree: Root, file: VFile) => {
visit(tree, 'mdxJsxFlowElement', (node) => {
if (node.name !== 'Note') return;
replaceSource(file, node, (s) => `**Note:**\n\n${s.inner(node)}`);
// transform the node for rendering...
});
};
}- A string replaces the node, along with the edits inside it.
- A function runs after every plugin.
s.stringify(node)ands.inner(node)(its children) give their Markdown, with the edits inside. - When a node is edited more than once, the last edit wins.
To edit a namespace only, like search for the records of Remark Structure, pass it as the last argument:
// the Markdown for LLMs keeps the tag, search records don't
replaceSource(file, node, (s) => s.stringify(node).replace(' [step]', ''), 'search');For search, a plugin adds the records of its nodes with data.structuredData.
Embedded Content
Nodes parsed from another source, like an included file, have positions in that source. Embed them with embedSource() to stringify them like your own content:
import { embedSource } from 'fumadocs-core/mdx-plugins/stringifier';
// replaces `node` with the nodes parsed from `otherSource`
embedSource(file, node, otherSource, otherTree.children);Other nodes parsed from a string must not keep their position, it doesn't point into your document.
Sätteri
The Sätteri compiler of Fumadocs MDX works the same way, with its own versions of these plugins.
How is this guide?
Last updated on
