HTML to PPTX JSX
Turn rendered HTML into an editable PPTX in the browser. The intended workflow is not a build pipeline: copy the original HTML, make the copy an exporter, lay every slide/page out vertically, measure rendered nodes, recreate each page with @artifact-kit/pptxgenjs-jsx JSX, and export from a button.
Required Path
Follow this sequence. Do not substitute a Node script, CLI exporter, server-side renderer, package install, Vite app, webpack build, or screenshot-only pipeline unless the user explicitly asks for that different workflow.
- Copy the original file. Treat the source HTML as read-only. Create a separate exporter HTML next to it, for example
name.pptx-export.html.
- Flatten the slides in the copy. If the original is a slideshow, carousel, route, tab set, or deck runtime, expand it so every slide/page is visible in one top-to-bottom container. Hidden, virtualized, inactive, or
display:none slides must be made measurable in the exporter copy.
- Add one export button. Put a fixed toolbar/button in the exporter copy only. Keep the original content visible for visual comparison.
- Use the CDN browser library. Load the CDN IIFE build of
@artifact-kit/pptxgenjs-jsx and Babel Standalone directly in the exporter page. Do not run pnpm install, npm install, or create a Node export script just to make a PPTX.
- Add measurement attributes. Mark each slide root with
data-ak-slide, data-ak-width, data-ak-height, and data-ak-px-per-in. Mark each DOM element needed in PPT with data-ak-measure="stable-id".
- Measure in the click handler. Inside the export button handler, call
await measureArtifacts({ document }), then use readSlideLayout(id), readPptBox(id), and readFontPt(id) for slide layout, placement, and text sizing.
- Recreate each page with inline JSX. Use
window.ArtifactKitPptxGenJsx components to build editable PPT content from measured boxes and source geometry. Create one <Slide> per visible HTML slide/page.
- Validate and export. Run
validateDeck(deck). If no errors are present, call renderPptx(deck, { fileName }). Open the downloaded PPTX and compare it against the exporter page when the environment allows.
Required Reading
Read these before coding the exporter JSX:
examples/generated/attention-pptx-export.html for the intended end-to-end exporter shape.
assets/browser-inline-jsx-template.html for the minimal CDN + Babel pattern.
references/pptxgenjs-jsx-measure-contract.md for data-ak-*, measureArtifacts, readPptBox, readFontPt, and readSlideLayout.
references/pptxgenjs-jsx-component-selection.md for component names and when to use them.
references/pptxgenjs-jsx-common-props.md for shared position, text, fill, line, image, and table props.
references/pptxgenjs-jsx-shape-props.md when rebuilding SVG/diagram primitives.
references/pptxgenjs-jsx-chart-props.md when using native charts.
references/pptxgenjs-jsx-component-manifest.json when uncertain whether a component or prop exists.
Read only when relevant:
references/svg-viewbox-mapping.md for SVG-heavy pages.
references/native-reconstruction-patterns.md for cards, diagrams, heatmaps, icons, arrows, and repeated UI patterns.
references/audit-checklist.md before final delivery.
references/pptxgenjs-jsx-all-upstream-props.md only when focused props docs do not answer a question.
If local node_modules/@artifact-kit/pptxgenjs-jsx already exists and appears newer than this skill, prefer its llms.txt, docs/, and component-manifest.json. Do not install it just to check docs.
Browser Inline Pattern
Use this pattern in the copied exporter page:
<script src="https://unpkg.com/@artifact-kit/pptxgenjs-jsx/dist/pptxgenjs-jsx.browser.iife.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel" data-presets="typescript,react">
/** @jsx pptxElement */
const {
Deck,
Slide,
Text,
Rect,
RoundRect,
LineBetween,
measureArtifacts,
pptxElement,
readFontPt,
readPptBox,
readSlideLayout,
renderPptx,
validateDeck,
} = window.ArtifactKitPptxGenJsx;
document.querySelector("#export-pptx").addEventListener("click", async () => {
await measureArtifacts({ document });
const deck = (
<Deck title="Measured deck" layout={readSlideLayout("slide-1")}>
<Slide background={{ color: "FFFFFF" }}>
<Text {...readPptBox("title-1")} fontSize={readFontPt("title-1")} bold margin={0}>
{document.querySelector('[data-ak-measure="title-1"]').textContent.trim()}
</Text>
</Slide>
</Deck>
);
const issues = validateDeck(deck);
if (issues.some((issue) => issue.level === "error")) throw new Error(JSON.stringify(issues, null, 2));
await renderPptx(deck, { fileName: "export.pptx" });
});
</script>
Do not use @jsxImportSource in inline Babel unless the React preset is explicitly configured for automatic runtime. The default inline-browser pattern is /** @jsx pptxElement */.
Measurement Rules
- Measure rendered DOM, not guesses. Any DOM-derived PPT element needs a
data-ak-measure id and readPptBox(id).
- Every slide root must declare source pixels and pixel-to-inch ratio, for example
data-ak-width="1600" data-ak-height="900" data-ak-px-per-in="120".
- Keep slides visible for measurement. Avoid
display:none, zero scale, inactive carousel pages, and virtualization in the exporter copy.
- Read measurement values after
await measureArtifacts({ document }), not at module parse time.
- Keep derived geometry as visible formulas so the mapping is auditable.
Reconstruction Rules
- Prefer editable native PPT objects over screenshots.
- Rebuild SVG primitives from the source
viewBox: rect -> Rect/RoundRect, circle/ellipse -> Ellipse, line/polyline/path arrows -> LineBetween, text -> Text, complex paths -> CustomGeometry when practical.
- Use
LineBetween with numeric x1, y1, x2, y2; do not pass it a measured box.
- Valid native chart types are
area, bar, bar3D, bubble, doughnut, line, pie, radar, and scatter. Do not use heatmap; rebuild heatmaps or matrices with editable Rect grids or Table cells.
- Use image fallback only for details that cannot be reasonably represented as editable PPT objects, and state the reason.
- Split complex JSX into small functions/components. Avoid one giant unreadable slide function.
Delivery Checklist
Before final response:
- Confirm the source file was not modified.
- Confirm the exporter copy contains a vertical slide/page container and export button.
- Confirm the CDN browser build is used and no package install or Node export script was introduced.
- Confirm
measureArtifacts, readPptBox, readFontPt, and readSlideLayout are used in the export flow.
- Confirm
validateDeck runs before renderPptx.
- Confirm the downloaded PPTX was opened or otherwise visually checked when the environment allows it.
1---2name: html-to-pptx-jsx3description: Create downloadable, editable PowerPoint decks from HTML pages by copying the source into a browser exporter page, laying slides out vertically, measuring DOM nodes, and using the CDN browser build of @artifact-kit/pptxgenjs-jsx with inline JSX. Use for local HTML files, generated web pages, dashboards, reports, slide-like Tailwind pages, SVG-heavy pages, or any workflow that needs HTML-to-PPTX reconstruction with DOM measurement rather than guessed coordinates.4---56# HTML to PPTX JSX78Turn rendered HTML into an editable PPTX in the browser. The intended workflow is not a build pipeline: copy the original HTML, make the copy an exporter, lay every slide/page out vertically, measure rendered nodes, recreate each page with `@artifact-kit/pptxgenjs-jsx` JSX, and export from a button.910## Required Path1112Follow this sequence. Do not substitute a Node script, CLI exporter, server-side renderer, package install, Vite app, webpack build, or screenshot-only pipeline unless the user explicitly asks for that different workflow.13141. **Copy the original file.** Treat the source HTML as read-only. Create a separate exporter HTML next to it, for example `name.pptx-export.html`.152. **Flatten the slides in the copy.** If the original is a slideshow, carousel, route, tab set, or deck runtime, expand it so every slide/page is visible in one top-to-bottom container. Hidden, virtualized, inactive, or `display:none` slides must be made measurable in the exporter copy.163. **Add one export button.** Put a fixed toolbar/button in the exporter copy only. Keep the original content visible for visual comparison.174. **Use the CDN browser library.** Load the CDN IIFE build of `@artifact-kit/pptxgenjs-jsx` and Babel Standalone directly in the exporter page. Do not run `pnpm install`, `npm install`, or create a Node export script just to make a PPTX.185. **Add measurement attributes.** Mark each slide root with `data-ak-slide`, `data-ak-width`, `data-ak-height`, and `data-ak-px-per-in`. Mark each DOM element needed in PPT with `data-ak-measure="stable-id"`.196. **Measure in the click handler.** Inside the export button handler, call `await measureArtifacts({ document })`, then use `readSlideLayout(id)`, `readPptBox(id)`, and `readFontPt(id)` for slide layout, placement, and text sizing.207. **Recreate each page with inline JSX.** Use `window.ArtifactKitPptxGenJsx` components to build editable PPT content from measured boxes and source geometry. Create one `<Slide>` per visible HTML slide/page.218. **Validate and export.** Run `validateDeck(deck)`. If no errors are present, call `renderPptx(deck, { fileName })`. Open the downloaded PPTX and compare it against the exporter page when the environment allows.2223## Required Reading2425Read these before coding the exporter JSX:26271. `examples/generated/attention-pptx-export.html` for the intended end-to-end exporter shape.282. `assets/browser-inline-jsx-template.html` for the minimal CDN + Babel pattern.293. `references/pptxgenjs-jsx-measure-contract.md` for `data-ak-*`, `measureArtifacts`, `readPptBox`, `readFontPt`, and `readSlideLayout`.304. `references/pptxgenjs-jsx-component-selection.md` for component names and when to use them.315. `references/pptxgenjs-jsx-common-props.md` for shared position, text, fill, line, image, and table props.326. `references/pptxgenjs-jsx-shape-props.md` when rebuilding SVG/diagram primitives.337. `references/pptxgenjs-jsx-chart-props.md` when using native charts.348. `references/pptxgenjs-jsx-component-manifest.json` when uncertain whether a component or prop exists.3536Read only when relevant:3738- `references/svg-viewbox-mapping.md` for SVG-heavy pages.39- `references/native-reconstruction-patterns.md` for cards, diagrams, heatmaps, icons, arrows, and repeated UI patterns.40- `references/audit-checklist.md` before final delivery.41- `references/pptxgenjs-jsx-all-upstream-props.md` only when focused props docs do not answer a question.4243If local `node_modules/@artifact-kit/pptxgenjs-jsx` already exists and appears newer than this skill, prefer its `llms.txt`, `docs/`, and `component-manifest.json`. Do not install it just to check docs.4445## Browser Inline Pattern4647Use this pattern in the copied exporter page:4849```html50<script src="https://unpkg.com/@artifact-kit/pptxgenjs-jsx/dist/pptxgenjs-jsx.browser.iife.js"></script>51<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>52<script type="text/babel" data-presets="typescript,react">53 /** @jsx pptxElement */54 const {55 Deck,56 Slide,57 Text,58 Rect,59 RoundRect,60 LineBetween,61 measureArtifacts,62 pptxElement,63 readFontPt,64 readPptBox,65 readSlideLayout,66 renderPptx,67 validateDeck,68 } = window.ArtifactKitPptxGenJsx;6970 document.querySelector("#export-pptx").addEventListener("click", async () => {71 await measureArtifacts({ document });7273 const deck = (74 <Deck title="Measured deck" layout={readSlideLayout("slide-1")}>75 <Slide background={{ color: "FFFFFF" }}>76 <Text {...readPptBox("title-1")} fontSize={readFontPt("title-1")} bold margin={0}>77 {document.querySelector('[data-ak-measure="title-1"]').textContent.trim()}78 </Text>79 </Slide>80 </Deck>81 );8283 const issues = validateDeck(deck);84 if (issues.some((issue) => issue.level === "error")) throw new Error(JSON.stringify(issues, null, 2));85 await renderPptx(deck, { fileName: "export.pptx" });86 });87</script>88```8990Do not use `@jsxImportSource` in inline Babel unless the React preset is explicitly configured for automatic runtime. The default inline-browser pattern is `/** @jsx pptxElement */`.9192## Measurement Rules9394- Measure rendered DOM, not guesses. Any DOM-derived PPT element needs a `data-ak-measure` id and `readPptBox(id)`.95- Every slide root must declare source pixels and pixel-to-inch ratio, for example `data-ak-width="1600" data-ak-height="900" data-ak-px-per-in="120"`.96- Keep slides visible for measurement. Avoid `display:none`, zero scale, inactive carousel pages, and virtualization in the exporter copy.97- Read measurement values after `await measureArtifacts({ document })`, not at module parse time.98- Keep derived geometry as visible formulas so the mapping is auditable.99100## Reconstruction Rules101102- Prefer editable native PPT objects over screenshots.103- Rebuild SVG primitives from the source `viewBox`: `rect` -> `Rect`/`RoundRect`, `circle/ellipse` -> `Ellipse`, `line/polyline/path arrows` -> `LineBetween`, text -> `Text`, complex paths -> `CustomGeometry` when practical.104- Use `LineBetween` with numeric `x1`, `y1`, `x2`, `y2`; do not pass it a measured box.105- Valid native chart types are `area`, `bar`, `bar3D`, `bubble`, `doughnut`, `line`, `pie`, `radar`, and `scatter`. Do not use `heatmap`; rebuild heatmaps or matrices with editable `Rect` grids or `Table` cells.106- Use image fallback only for details that cannot be reasonably represented as editable PPT objects, and state the reason.107- Split complex JSX into small functions/components. Avoid one giant unreadable slide function.108109## Delivery Checklist110111Before final response:1121131. Confirm the source file was not modified.1142. Confirm the exporter copy contains a vertical slide/page container and export button.1153. Confirm the CDN browser build is used and no package install or Node export script was introduced.1164. Confirm `measureArtifacts`, `readPptBox`, `readFontPt`, and `readSlideLayout` are used in the export flow.1175. Confirm `validateDeck` runs before `renderPptx`.1186. Confirm the downloaded PPTX was opened or otherwise visually checked when the environment allows it.