Core Plugins

Export

Download the page, a region, or a data source as a file.


Overview

The x-export directive turns its host element into a download action. The whole page, a target section, or an $x data source can be exported. Supported formats are PDF, PNG, JPEG, WebP, CSV, and JSON.

PDFs go through the browser's native print pipeline, so users get the familiar "Save as PDF" dialog with proper multi-page layout, vector text (selectable and copy-pasteable), and the page's own @media print rules. Whole-page PDFs print the whole page; targeted PDFs scope the print to the chosen subtree via a temporary print stylesheet. Raster image formats (PNG, JPEG, WebP) use html2canvas-pro, lazy-loaded from the jsDelivr CDN on first use.


Setup

Export is included in manifest.js with all core plugins, or can be selectively loaded.

<script src="https://cdn.jsdelivr.net/npm/mnfst@latest/lib/manifest.min.js"></script>

Triggers

Buttons

Add x-export to any clickable element. With no options it snaps the whole page as a PDF. Other formats are defined by a modifier.


<!-- PDF -->
<button x-export>PDF</button>

<!-- Image formats -->
<button x-export.png>PNG</button>
<button x-export.jpg>JPG</button>
<button x-export.webp>WEBP</button>

<!-- Data formats -->
<div x-data="{ rows: [
    { id: 1, name: 'Acme Co.', plan: 'Pro', mrr: 240 },
    { id: 2, name: 'Globex', plan: 'Starter', mrr: 49 }
    ] }">
    <button x-export="{ format: 'csv', data: rows, filename: 'rows.csv' }">CSV</button>
    <button x-export="{ format: 'json', data: rows, filename: 'rows.json' }">JSON</button>
</div>

Visual formats (PDF, PNG, JPEG, WebP) snapshot the page or a target element. Data formats (CSV, JSON) serialize an $x source or inline value — covered in detail in Data Sources below.

UI elements that shouldn't appear in the snapshot (headers, sidebars, navigation, the export button itself) can be marked with data-no-export. The filter applies to every visual export on the page.

The downloaded filename is configurable without switching to the object form. A data-filename attribute works on any element. On an anchor link trigger, the standard HTML download attribute is honored as well.

<button x-export.png data-filename="report.png">Download report</button>
<a x-export.pdf href="#chart" download="chart.pdf">Save chart</a>

To control resolution or dimensions of a raster image, use the object form. resolution is the pixel-density multiplier (defaults to the device pixel ratio so the exported image matches what's on screen); width and height set explicit output dimensions.

<button x-export="{ format: 'png', resolution: 2 }">Retina PNG</button>
<button x-export="{ format: 'jpeg', width: 1200 }">1200 px wide JPG</button>
<button x-export="{ format: 'webp', width: 1200, height: 800 }">Sized WEBP</button>

For more control, pass an object expression. The target property is a CSS selector pointing at the element to snapshot. Anything outside it is ignored.


<div id="report">
    <h2>Quarterly Report</h2>
    <p>...</p>
</div>

<button x-export="{ format: 'pdf', target: '#report', filename: 'q3-report.pdf' }">Download PDF report</button>

When x-export is on an <a> whose href starts with #, the directive treats the fragment as the target. Clicking downloads the matched element instead of scrolling.


<a x-export.png href="#chart">Save chart as PNG</a>

This pairs well with a normal in-page anchor as a "download this section" companion.


When x-export is on an <a> whose href points to another page, the directive rewrites the href to append ?export=<format>. The browser navigates normally. The destination page picks up the URL signal and exports itself after loading.

<!-- The link becomes /reports/q3?export=pdf -->
<a x-export.pdf href="/reports/q3">Download Q3 report</a>

The pattern keeps the intent on the link that expresses it, and the capability on the page that knows what's exportable. Random visitors never trigger downloads. Only those arriving via an export link, or a pasted URL with the param, will.


Data Sources

For tabular and structured data, point at a $x source by name. The directive serializes the source as CSV or JSON and triggers a download.


<!-- Full source as CSV -->
<button x-export="{ format: 'csv', source: 'customers', filename: 'customers.csv' }">
    Export customers
</button>

<!-- Filtered subset using existing query helpers -->
<button x-export="{ format: 'csv', data: $x.customers.$search(term, 'name') }">
    Export search results
</button>

<!-- Full JSON tree -->
<button x-export="{ format: 'json', source: 'settings' }">
    Export settings
</button>

CSV output handles RFC-4180 quoting automatically. Values containing commas, quotes, or newlines are properly escaped. The header row is the union of keys across all rows, so heterogeneous arrays export faithfully.


Magic Property

The $export magic provides the same functionality as x-export, and is useful for custom trigger conditions, multi-step workflows, or non-clickable triggers.


<!-- Validate, then export -->
<form @submit.prevent="$refs.form.checkValidity() && await $export({ format: 'csv', data: rows })">
    ...
</form>

<!-- Require sign-in before export -->
<button @click="$auth.isAuthenticated && $export({ format: 'pdf', target: '#dashboard' })">
    Download (signed-in only)
</button>

All of $export's options are identical to those of x-export.


Options

Property Type Default Description
format String 'pdf' One of pdf, png, jpeg, webp, csv, json
target String / Element <body> CSS selector or element to snapshot. Visual formats only.
source String Name of a $x data source to export. csv / json only.
data Array / Object Inline data to export instead of a $x source. csv / json only.
filename String export-<timestamp>.<ext> Suggested download name. Falls back to a download attribute on anchor hosts, then a data-filename attribute, then a timestamped default.
resolution Number device pixel ratio Pixel-density multiplier for raster image exports. Default matches the host display — 1 on standard monitors, 2 on retina — so the exported image looks like what you see on screen. Set explicitly (e.g. 2 or 3) for hardware-independent renders.
width Number natural width Output canvas width in pixels for raster image exports. Overrides the target's natural width.
height Number natural height Output canvas height in pixels for raster image exports. Overrides the target's natural height.
quality Number (0–1) 0.95 JPEG / WebP compression quality
backgroundColor String page background Solid background for raster exports (PNG, JPEG, WebP). Defaults to the page's effective background. Pass 'transparent' to disable the fill (useful for icon / logo exports). PDFs render the page CSS directly and ignore this option.
pageSize String 'a4' PDF page size — a4, a3, letter, legal, etc. Passed through to the print pipeline's @page rule. Users can still override in the browser's print dialog.
trigger String 'click' 'click' (default) or 'url'. With 'url' the export fires on page load if the URL has the export param.
urlParam String 'export' URL query-param name to watch when trigger: 'url'
delay Number 0 Milliseconds to wait after a url trigger fires before snapshotting. Useful when charts or animations need to settle.

Batch and CI Exports

The mnfst-export CLI runs the same exports from Node. It's the right tool for build pipelines, scheduled jobs, and any case where no human is around to click. The CLI supports the same six formats as the directive, plus an rss format for blog feeds.

# Snapshot a single route as PDF
npx mnfst-export --pdf --path /reports/q3 --target "#report"

# Whole project at once (reads manifest.export.routes from manifest.json)
npx mnfst-export

# Data source as CSV
npx mnfst-export --csv --path /admin/customers --source customers

Routes can be configured in manifest.json so the same npx mnfst-export runs in any environment.

manifest.json
{ "export": { "output": "exports", "routes": [ { "path": "/reports/q3", "format": "pdf", "target": "#report" }, { "path": "/customers", "format": "csv", "source": "customers" }, { "path": "/blog", "format": "rss", "source": "posts", "map": { "link": "slug" } } ] } }
Option Type Default Description
output string "exports" Output folder relative to the project root
routes object[] [] Per-route export entries. Each takes the same fields as the directive's object form (path, format, target, source, filename, pageSize, etc.)
rss object inherited Channel defaults: { title, link, description }. Falls back to manifest.name, manifest.live_url, and manifest.description.

The CLI spins up a static server, opens each route in headless Chromium, waits for the manifest:render-ready signal, then snapshots or serializes whatever the route exposes. Visual formats use Puppeteer's native page.pdf() and page.screenshot(), which are more reliable in headless than the in-browser libraries.

Run npx mnfst-export --help for the full list of flags. Puppeteer is a peer dependency. Install it once in the project.

npm i -D puppeteer