# ExportOptions

Import it from `@grafloria/renderer`.

Export options.

The first three are the original contract. The rest were added when the seam
was actually implemented (`export/`), and every one of them is optional — the
zero-argument call `renderer.export()` produces a standalone, styles-inlined
SVG of the whole diagram.

```ts
interface ExportOptions
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `scale?` | `number` |  | Image scale (default: 1) |
| `quality?` | `number` |  | JPEG/WebP quality 0-1 (default: 0.92) |
| `backgroundColor?` | `string` |  | Background color (default: transparent) |
| `viewport?` | `Rectangle` |  | World-space rectangle to export. Default: the diagram's content bounds — i.e. the whole diagram, not whatever the user happens to be looking at. |
| `padding?` | `number` |  | Margin (world units) around the content bounds. Default 20. Ignored with an explicit `viewport`. |
| `foreignObject?` | `ForeignObjectMode` |  | How to serialize `<foreignObject>` (HTML-in-SVG) nodes. Default `'serialize'`. |
| `captureForeignObject?` | `(vnode: VNode) => string \| undefined` |  | Supply the live HTML mounted inside a foreignObject. The VNode tree does not contain it (the patcher treats those subtrees as opaque), so a headless exporter cannot know it — a browser-side caller can hand it back here. |
| `customNodes?` | `readonly CustomNodeCapture[]` |  | CUSTOM-NODE (HTML-layer) CONTENT to place into the export. |
| `htmlFallback?` | `HtmlFallbackMode` |  | How to export a custom node that could only be captured as HTML. Default `'foreignObject'`. |
| `customNodeTimeout?` | `number` |  | THE BOUND on waiting for an ASYNC custom-node painter, in milliseconds. Default 5000. |
| `assetFetcher?` | `AssetFetcher` |  | TIER 2 for EXTERNAL image URLs (`<img src="https://…">` inside a widget, a panel node's logo). `await export(…)` — every format — first tries the environment's own fetch, which succeeds for same-origin assets and for any server that allows CORS; when that is refused, THIS fetcher is consulted (route the URL through your own proxy, a service worker, an app cache); when both fail the reference is … |
| `resolvedAssets?` | `ReadonlyMap<string, string>` |  | PRE-RESOLVED external assets: URL → `data:` URI. Every `<image href>` in the export — the renderer's own tree (a panel node's image/icon) and widget captures alike — whose URL appears here is substituted with the supplied bytes, by a PURE, synchronous pass (`inlineAssets` in `export/assets.ts`). No network is touched. |
| `assetTimeout?` | `number` |  | Bound on fetching ONE external image, per tier, in milliseconds. Default 5000 — the same figure as {@link customNodeTimeout}, for the same reason: a dead URL must not hang a print job. On expiry the image degrades to the tier-3 warning. |
| `assetMaxBytes?` | `number` |  | Cap on one fetched image's size, in bytes. Default 5MB — a data: URI is ~33% bigger than the file it carries. Over the cap the image is refused with a warning; the cap is terminal (a proxy would return the same bytes, so tier 2 is not asked). |
| `onWarnings?` | `(warnings: string[]) => void` |  | FIDELITY REPORT. `IRenderer.export()` returns a bare string, so it has nowhere to put the caveats an export hit — and for years it simply threw them away, which is how a blank widget reaches a customer with no diagnostic anywhere. |
| `embedFontCss?` | `string` |  | CSS injected verbatim into the exported SVG's `<defs>`. The font seam: an `@font-face` with a `data:` URI `src` makes the file carry its own glyphs. We declare font families; we do not embed or subset fonts for you. |
| `rasterBackend?` | `RasterBackend` |  | Rasterizer for `png` / `jpeg` / `webp`. Defaults to a canvas-based backend when one exists (browser main thread or worker via OffscreenCanvas). In plain Node there is no SVG engine, so raster export THROWS unless you pass one (resvg-js / sharp / puppeteer). SVG export never needs this. |
| `scope?` | `ExportScope` |  | WHAT to export. |
| `includeIds?` | `Iterable<string>` |  | Export only these node/link ids. The tree is PRUNED to them, so an un-selected node's markup (and its labels) is not merely cropped out of view — it is not in the file. Overridden by `scope: 'selection'`, which reads the live selection. |
| `maxSize?` | `number` |  | Cap on the exported image's size per side, in px. Default 4000. |
| `minSize?` | `number` |  | Floor on the exported image's size per side, in px. Default 1. |
| `xmlDeclaration?` | `boolean` |  | Prepend the `<?xml …?>` prolog to an SVG export. Default false. |
| `embedModel?` | `boolean` |  | Carry the source model INSIDE the exported artifact, so it can be re-imported and edited losslessly (`importDiagram`). An SVG gets it in `<metadata>`; a PNG gets an `iTXt` chunk. |
| `embedModelCreatedAt?` | `string` |  | The embedded envelope's `createdAt`. Supply it to keep an `embedModel` export DETERMINISTIC — otherwise the envelope is stamped with the wall clock and two exports of the same diagram differ in their bytes. |
| `pdf?` | `PdfExportOptions` |  | Page size, orientation, margins and document metadata for `export('pdf')`. |
| `embedFonts?` | `FontSource[]` |  | Fonts to EMBED, as `@font-face` rules with base64 `data:` URIs — so the file renders in the right typeface on a machine that has never heard of it. |
