save-as-pdf
Save as PDF
Reformat the current HTML design into a paginated, paper-ready PDF. The "Instant" export already gives the user a PDF at the design's native pixel size — this path is for when they want real pages.
Do NOT rasterize the page into a PDF. Never use jsPDF, html2canvas, dom-to-image, or any other canvas/screenshot-to-PDF approach — they produce blurry, non-selectable, oversized output, and do not generate a PDF binary yourself. PDF export is print-based: a print-ready copy is handed to show_pdf_export_dialog and the browser's own print engine renders crisp, selectable, text-based pages. The only supported way to make a copy print-ready is a component that owns its print geometry — the doc_page starter for documents, or a source already built on <deck-stage> or <doc-page>. Do not hand-author @page rules or print CSS resets.
Steps
-
Read the current HTML design file to understand its structure and content. Re-read it on every PDF request, even if you read it or made a print copy earlier in this conversation — the user may have changed content or tweak values (the Tweaks panel writes into the source file) since then.
-
Write the print copy. Always write it fresh from the source you just read — an existing
-printcopy from an earlier request is a stale snapshot, and reusing or only partially updating it ships outdated values to the PDF. The print file path is the source path with-printinserted before the extension — same directory, same basename. If the source isslides/deck.html, writeslides/deck-print.html; if the source isweb/index.html, writeweb/index-print.html. Do NOT use the deck title or project name as the filename, and do NOT write to the project root if the source is in a subdirectory — any change in directory depth breaks every relative URL (@font-facesrc: url(...),<img src>,<link href>, CSSbackground: url(...)) and the print tab shows missing images and system-font fallbacks.If the source is already built on
<deck-stage>or<doc-page>, the copy is the source plus content-level print rules only. Both components own their print geometry — never add an@pagerule or reflow their layout. For<deck-stage>decks, setdata-deck-activeon every direct-child slide (not just the current one) so[data-deck-active]-keyed entrance styles resolve on every page — each slide is already one page. For<doc-page>documents there is nothing structural to do.Otherwise, rebuild the content as a paged document on the doc_page starter. Call
copy_starter_componentwithkind: "doc_page.js"(once per project — the component file persists), then write the print copy as a<doc-page size="letter" margin="0.75in">document (size="a4"when the user is clearly non-US): pour the source's content into it as normal flowing HTML, keeping the design's typography, colors, and imagery intact. The component owns the sheet, the pagination, and all print geometry — do NOT write your own@pagerule, print-CSS reset, page-card divs, orbreak-after: pagefake sheets. Usebreak-before: pageonly where a section genuinely starts a new chapter; long tables get a<thead>so the header repeats on every page.A fixed-canvas design (poster, social graphic, infographic) also goes through the doc_page rebuild, with one decision: the page. Print it at its true dimensions —
<doc-page width="18in" height="24in" margin="0">, the page IS the design — or scale it onto standard paper —<doc-page size="letter" content-width="960px" content-height="1440px">, where the content lays out at its authored size and the component scales it to fit the printable area. When the user's intent between the two isn't clear from their request, ask — in plain terms (print it poster-sized, or fit it onto letter paper?) — before exporting. Never hand-scale with your own CSS transforms; the component owns the scaling either way.