Chinese, Japanese and Korean PDFs with no font upload
Chinese, Japanese and Korean text now renders out of the box — markdown, templates and canvas boards all draw CJK with a built-in Noto Sans fallback, and the new lang option picks the script and sets the PDF's /Lang.
Chinese, Japanese and Korean text now renders without uploading a font. Send a Japanese paragraph to POST /api/v1/md, render a doc() template with Chinese data, or convert an Obsidian canvas board with Korean cards — the CJK characters draw correctly, and the parts that aren't CJK keep using your chosen font.
The renderer loads only the Noto Sans CJK slices that cover the characters in your document — typically a few hundred KB, and nothing at all when a document has no CJK text. Four scripts are built in: Noto Sans SC (Simplified Chinese), TC (Traditional Chinese), JP (Japanese) and KR (Korean), each in regular and bold.
A new lang option picks the script and is available everywhere: the lang body option or YAML frontmatter on POST /api/v1/md, doc({ lang: "ja" }) in the DSL, options.lang on POST /api/v1/preview, POST /api/v1/render and POST /api/v1/canvas. Use a BCP 47 tag — ja, ko, zh-Hans, zh-Hant, zh-TW and so on. Omit it and the text decides: any kana means Japanese, any Hangul means Korean, and Han-only text is treated as Simplified Chinese.
lang also writes the PDF's /Lang catalog entry. That alone is an accessibility win — screen readers and PDF/UA checkers use it to select the right pronunciation — and it's set on every endpoint that accepts the option.
A custom font still wins for the characters it covers, so a branded Japanese typeface on a font-family renders with the brand and the built-in slices only fill in what it lacks. See the font guide at /skills/pdf-fonts.md for the full picture, including what still needs a custom font (Cyrillic, Greek, Vietnamese, Georgian, Armenian) and what isn't supported yet (right-to-left and complex-script text).