keystatic
keystatic copied to clipboard
gracefully handle `footnoteReference` and `footnoteDefinition` nodes in mdx field
currently, when an mdx document has a footnote, the keystatic mdx field errors with the following error message:
Field validation failed: content: Unexpected error: Error: Unhandled type footnoteReference Unhandled type footnoteDefinition
mdx document used:
---
title: test
---
Some text.[^1]
[^1]: Footnote content.
in case it's useful to someone, i am currently replacing native markdown footnotes with a custom mark <Footnote> component, and using a remark plugin to split that into footnote reference and definition:
/** @typedef {import("mdast-util-mdx").MdxJsxAttribute} MdxJsxAttribute */
/** @typedef {import("mdast-util-mdx").MdxJsxTextElement} MdxJsxTextElement */
/** @typedef {import("mdast-util-mdx").MdxJsxFlowElement} MdxJsxFlowElement */
import { SKIP, visit } from "unist-util-visit";
export function withMdxFootnotes() {
return function transformer(/** @type {import("mdast").Root} */ tree) {
let count = 1;
/** @type {MdxJsxTextElement[]} */
const footnotes = [];
visit(tree, "mdxJsxTextElement", (node, index, parent) => {
if (node.name === "Footnote") {
/** @type {MdxJsxAttribute} */
const countAttribute = {
type: "mdxJsxAttribute",
name: "count",
value: String(count),
};
/** @type {MdxJsxTextElement} */
const reference = {
type: "mdxJsxTextElement",
name: "FootnoteReference",
attributes: [countAttribute],
children: [],
};
/** @type {MdxJsxTextElement} */
const content = {
type: "mdxJsxTextElement",
name: "FootnoteContent",
attributes: [countAttribute],
children: node.children,
};
// @ts-expect-error Parent node exists.
parent.children.splice(index, 1, reference);
footnotes.push(content);
count++;
}
return SKIP;
});
if (footnotes.length > 0) {
/** @type {MdxJsxFlowElement} */
const section = {
type: "mdxJsxFlowElement",
name: "FootnotesSection",
attributes: [],
// @ts-expect-error Should be fine to set `MdxJsxTextElement` children.
children: footnotes,
};
tree.children.push(section);
}
};
}
@stefanprobst How did you manage to fix this? How to use this code snippet exactly? I'm struggling with the same issue.
@adamlewkowicz i put together an example here: https://github.com/stefanprobst/keystatic-footnotes
in an .mdx file it will look like this:
This text has a footnote.<Footnote>This is the footnote text.</Footnote> This is the rest of the paragraph.
in the keystatic ui, it will look like this:
@stefanprobst Thanks a lot for the example! I've used this setup with remote-mdx and it's working 👍