docs: add KaTeX Portable Text recipe#1885
Conversation
|
|
All contributors have signed the CLA ✍️ ✅ |
There was a problem hiding this comment.
The recipe itself is a reasonable, additive docs page: wrapping EmDash's PortableText to render KaTeX display math is a useful site-level technique and the core approach is sound. However, the Astro 7 Markdown-configuration snippet is unverified and inconsistent with what the repo's lockfile shows about Astro 7, and two of the TypeScript snippets won't typecheck as written. I also found a minor docs-style issue.
What I checked:
- Read the new
docs/src/content/docs/guides/katex.mdxand the sidebar change indocs/astro.config.mjs. - Verified
emdash/uiexportsPortableTextandPortableTextBlock(fromastro-portabletext), but the rootemdashpackage exports a different, genericPortableTextBlock. - Checked the lockfile: Astro 7.0.0 resolves to
@astrojs/markdown-satteri, not@astrojs/markdown-remark, and the standardunifiedpackage takes no options object of{ remarkPlugins, rehypePlugins }. - Confirmed the docs build only validates Markdown/MDX; it does not typecheck or execute the embedded snippets.
Headline conclusion: the Portable Text wrapper parts look correct, but please fix the Astro 7 Markdown-config section and the TypeScript types before this recipe goes live.
| Astro 7 uses a Markdown processor API. If you need math in Markdown or MDX files, | ||
| configure `unified()` instead of the deprecated `markdown.remarkPlugins` and | ||
| `markdown.rehypePlugins` options: | ||
|
|
||
| ```js title="astro.config.mjs" | ||
| import { unified } from "@astrojs/markdown-remark"; | ||
| import rehypeKatex from "rehype-katex"; | ||
| import remarkMath from "remark-math"; | ||
| import { defineConfig } from "astro/config"; | ||
|
|
||
| export default defineConfig({ | ||
| markdown: { | ||
| processor: unified({ | ||
| remarkPlugins: [remarkMath], | ||
| rehypePlugins: [rehypeKatex], | ||
| }), | ||
| }, |
There was a problem hiding this comment.
[needs fixing] This section tells readers to configure Astro 7's Markdown engine with import { unified } from "@astrojs/markdown-remark" and processor: unified({ remarkPlugins: [remarkMath], rehypePlugins: [rehypeKatex] }). That is unverified and appears inconsistent with the project's own lockfile: astro@7.0.0 resolves to @astrojs/markdown-satteri, not @astrojs/markdown-remark. The standard unified package also does not accept an options object of { remarkPlugins, rehypePlugins }; that shape belongs to createMarkdownProcessor-style helpers, while markdown.processor expects a processor function/maker. Finally, markdown.remarkPlugins/rehypePlugins are not deprecated in the Astro 6.1.3 that this repo and EmDash target. Because the docs build only validates Markdown syntax, this snippet is not typechecked or executed. Please either confirm the snippet against Astro 7's actual markdown.processor API or replace it with a safe, version-appropriate pointer to the Astro docs.
| renderer for normal content and only intercepts formulas. | ||
|
|
||
| ```ts title="src/components/math-portable-text.ts" | ||
| import type { PortableTextBlock } from "emdash"; |
There was a problem hiding this comment.
[needs fixing] The root emdash package exports a generic PortableTextBlock with an index signature ([key: string]: unknown), so block.children is typed as unknown. The code on lines 114–117 then calls .filter(...).map(...).join(...) on it, which will not typecheck. Import the typed PortableTextBlock (and PortableTextSpan) from emdash/ui instead, since that re-exports astro-portabletext's types.
| import type { PortableTextBlock } from "emdash"; | |
| import type { PortableTextBlock, PortableTextSpan } from "emdash/ui"; |
| block.children | ||
| ?.filter((child) => child._type === "span") | ||
| .map((child) => child.text) | ||
| .join("") ?? ""; |
There was a problem hiding this comment.
[needs fixing] Even with the correct PortableTextBlock import, .filter((child) => child._type === "span") does not narrow the array element type, so .map((child) => child.text) is not guaranteed to be valid for every element in the union. Add a type predicate or cast the children to PortableTextSpan[].
| block.children | |
| ?.filter((child) => child._type === "span") | |
| .map((child) => child.text) | |
| .join("") ?? ""; | |
| const text = | |
| ((block.children ?? []) as PortableTextSpan[]) | |
| .filter((child) => child._type === "span") | |
| .map((child) => child.text) | |
| .join("") ?? ""; |
| in rich text fields. | ||
| </Aside> | ||
|
|
||
| ## Install KaTeX |
There was a problem hiding this comment.
[suggestion] Per the Documentation Style Guide, every code block should be introduced by a full, standalone sentence; don't lead with only a bare heading. Add a sentence before the install command, e.g. "Install KaTeX in your Astro project."
775503d to
cfcefff
Compare
cfcefff to
250ee45
Compare
What does this PR do?
Adds a small documentation recipe for rendering LaTeX math in EmDash Portable Text content with KaTeX on Astro 7.
The page explains why Astro Markdown plugins do not process CMS Portable Text fields directly, shows the Astro 7
markdown.processor: unified(...)setup for Markdown/MDX files, and demonstrates a modest site-levelPortableTextwrapper for display math blocks.Type of change
Checklist
pnpm typecheckpassespnpm lintpassespnpm testpasses (or targeted tests for my change)pnpm formathas been runmessages.pochanges except in translation PRs — a workflow extracts catalogs on merge tomain.AI-generated code disclosure
Screenshots / test output
Docs-only verification run:
pnpm exec prettier --write docs/src/content/docs/guides/katex.mdx pnpm --filter docs build pnpm lint:quickpnpm --filter docs buildcompleted successfully and prerendered/guides/katex/.pnpm lint:quickcompleted with zero diagnostics.