The Markdown links remote images
Inlining the stylesheet does not inline the pictures. An image referenced by URL still fails for a reader who is offline or behind a different network.
Markdown is not a document, it is instructions for making one. The moment the file leaves your process - into an email client, an archive, a ticket, another team's viewer - the renderer changes, and with it the tables, the code blocks and the task lists.
The release notes that looked right in the app arrive with tables collapsed into runs of pipes, or as unstyled black-on-white text that nobody wants to read.
Parse the Markdown with a spec-compliant parser, put the result inside a full document, and inline the stylesheet so nothing is fetched at open time.
import { readFile, writeFile } from "node:fs/promises";
import { marked } from "marked";
const body = marked.parse(await readFile("notes.md", "utf8"), { gfm: true });
const css = await readFile("document.css", "utf8");
await writeFile(
"notes.html",
`<!doctype html><html lang="en"><head><meta charset="utf-8">
<style>${css}</style></head><body><main>${body}</main></body></html>`
);
// Nothing is fetched when this file is opened: no font URL, no stylesheet,
// no image host. That is what makes it survive being forwarded.The call above is small. Everything around it is the system — and the system is what you would be signing up to own.
Inlining the stylesheet does not inline the pictures. An image referenced by URL still fails for a reader who is offline or behind a different network.
Tables and task lists are GitHub extensions, not CommonMark. Rendering them yourself is precisely what stops the recipient's viewer from deciding whether they exist.
Markdown allows raw HTML through, so content from a user is a script injection surface unless it is sanitized before it becomes a document.
A single HTML file has no pages, headers or footers. When the recipient will print it or archive it, PDF is the format that carries that structure.
One HTML document with the template stylesheet inlined: CommonMark plus GitHub tables and task lists, serialized from the rendered DOM.
One successful, non-cached capture costs one credit. Failures, including platform failures, cost zero; cache hits cost zero.
The Markdown carries large embedded data URLs and the request body passes the limit.
HTTP 413 · terminal
A remote image or font referenced by the content never resolves and the capture budget runs out.
HTTP 500 · retryable
Swap the example for a page you care about. The runner keeps every option from this guide, and carries the whole configuration into the playground — no retyping, no starting over.
Written by PageCapture Engineering. Reviewed by PageCapture render maintainers. Verified 2026-08-26 by running the published code against a fixture.
The recipe was normalized through the public contract and its Markdown rendered through the template used by the engine; the CI fixture run has not executed this piece yet.
Sources support the browser and API behaviors named above. PageCapture-specific limits and billing are taken from the public contract; external sources are used for the underlying browser behavior.
Defines the base syntax the template parses.
Defines the table and task list extensions cited as the ones that go missing.
Paste the Markdown and read the document that comes back, before wiring anything.
When the recipient will print or archive it, pages and margins are what HTML does not carry.
The structure a paginated document needs once HTML stops being enough.
How Markdown and HTML inputs are accepted, and which output formats they can take.