Render dark-mode PDFs in TypeScript with fetch
One field flips the render's color scheme: colorScheme: dark emulates a visitor with prefers-color-scheme: dark before the page paints.
colorScheme takes light, dark, or site, and light is the default. dark emulates the media query before navigation, so the page's own dark stylesheet wins on the first paint instead of flashing light; site leaves the decision to the page. It moves only pages that answer prefers-color-scheme, so a page with no dark stylesheet renders identically in both.
The recipe
import { writeFile } from "node:fs/promises";
const ORIGIN = "https://webcapture.io";
interface Receipt {
id: string;
bytes: number;
attempts: number;
remaining: number;
sourceUrl: string;
sourceType: "url" | "html";
download: string;
}
const res = await fetch(`${ORIGIN}/v1/convert`, {
method: "POST",
headers: {
"Authorization": "Bearer wc_your_key",
"Content-Type": "application/json",
},
body: JSON.stringify({"url": "https://example.com/", "colorScheme": "dark"}),
});
const receipt = (await res.json()) as Receipt;
// receipt.download: ${ORIGIN}/v1/conversions/cnv_9f2c01ab.pdf
const file = await fetch(receipt.download, {
headers: { "Authorization": "Bearer wc_your_key" },
});
await writeFile("page-dark.pdf", Buffer.from(await file.arrayBuffer()));
The choice is per call, so the same url can render both schemes in two calls and ship whichever the user's context needs. Dark mode is where pdf renders most often betray a site: a browser screenshot inherits the visitor's scheme, while an API render needs the field spelled out, which is exactly what this body does.
Same-key GET: 401 without it; 404 for another key.
The fields this recipe uses
colorScheme: light or dark renders the page as if the visitor preferred that scheme; site keeps the page's own choice; light is the default.
Related
- Next: Get a free key to run this TypeScript recipe, or read the API docs.
- More recipes: TypeScript: convert from a URL, Python: wait for the page, TypeScript: markdown.
- The webcapture API reference: every field the convert endpoint admits, with the response shapes and the error table.
- The recipes hub: the same endpoint in the other languages.
- Going deeper: the formatting guide covers colorScheme next to the other per-request tuning the print accepts.
- The free URL to PDF tool: try the render in a browser before you wire the call.
Method
Source: convert field reference, checked 2026-10-05. Corrections.