Document Viewer: Getting Started
Install peer dependencies, copy pdfium.wasm to your public dir, and render your first PDF, image, text, or markdown document.
This guide walks through installing DocumentViewer, hosting the PDFium WebAssembly binary, and rendering each of the four supported formats.
Install
pnpm add @meldui/vue @meldui/tabler-vue vue
# EmbedPDF peer dependencies. All Phase 1 plugins are always registered by the
# viewer (the `features` prop gates UI, not registration), so the full Phase 1
# set must be installed even if you only enable a few features.
pnpm add @embedpdf/core @embedpdf/engines @embedpdf/models @embedpdf/pdfium \
@embedpdf/plugin-document-manager @embedpdf/plugin-viewport \
@embedpdf/plugin-scroll @embedpdf/plugin-render @embedpdf/plugin-tiling \
@embedpdf/plugin-zoom @embedpdf/plugin-rotate @embedpdf/plugin-spread \
@embedpdf/plugin-pan @embedpdf/plugin-fullscreen \
@embedpdf/plugin-interaction-manager @embedpdf/plugin-selection \
@embedpdf/plugin-search @embedpdf/plugin-bookmark @embedpdf/plugin-thumbnail \
@embedpdf/plugin-export @embedpdf/plugin-print @embedpdf/plugin-commands \
@embedpdf/plugin-history @embedpdf/plugin-annotation
# Phase 2 plugins are only registered when their feature flag is on — install
# them only if you enable stamps / signature / redaction / forms / attachments:
# @embedpdf/plugin-stamp @embedpdf/plugin-signature @embedpdf/plugin-redaction
# @embedpdf/plugin-form @embedpdf/plugin-attachment
The first five plugins are the core rendering pipeline; the rest are the Phase 1 view-control, navigation, output, and annotation plugins that the viewer always registers. See the Bundle & Perf guide for the complete plugin → feature mapping.
Host the PDFium WASM binary
EmbedPDF ships PDFium as a .wasm file in @embedpdf/pdfium/dist/pdfium.wasm. Your app needs to serve it at a stable URL so DocumentViewer can load it on demand. Copy it into your public directory at build time:
# Add to your build script (Astro, Vite, Nuxt, Phoenix, etc.)
cp node_modules/@embedpdf/pdfium/dist/pdfium.wasm public/pdfium.wasm
Then pass the URL to the component via wasmUrl:
<DocumentViewer source="/sample.pdf" wasm-url="/pdfium.wasm" />
Why self-host?
- Same origin as your app — no CDN dependency, no CORS, no third-party domain.
- Works in air-gapped or enterprise environments.
- Cached independently of your JS bundle.
A root-relative wasmUrl like /pdfium.wasm works in both worker and main-thread mode (it is resolved against document.baseURI). Only bare relative paths such as pdfium.wasm or ./pdfium.wasm hit the worker-mode resolution issue (see Troubleshooting). To run on the main thread, pass :worker="false".
Render a PDF
The minimum viable usage:
<script setup lang="ts">
import { DocumentViewer } from '@meldui/vue'
</script>
<template>
<DocumentViewer source="/sample.pdf" wasm-url="/pdfium.wasm" />
</template>
source accepts a URL string, a File, a Blob, or an ArrayBuffer. The MIME type is auto-detected; you can override with mime-type="application/pdf" if your URL has no extension.
Render an image, text, or markdown document
DocumentViewer dispatches to a format-specific renderer based on the detected MIME type. No extra setup needed — the toolbar and side-panel chrome are shared.
<!-- Image -->
<DocumentViewer source="/diagram.png" mime-type="image/png" />
<!-- Plain text -->
<DocumentViewer source="/changelog.txt" mime-type="text/plain" />
<!-- Markdown -->
<DocumentViewer source="/README.md" mime-type="text/markdown" />
Capture a ref for the programmatic API
To call methods like loadAnnotations, createAnnotation, or saveAsCopy, capture a template ref typed as DocumentViewerInstance:
<script setup lang="ts">
import { ref } from 'vue'
import { DocumentViewer, type DocumentViewerInstance } from '@meldui/vue'
const viewer = ref<DocumentViewerInstance | null>(null)
async function exportAnnotations() {
const items = await viewer.value?.exportAnnotations()
console.log(items)
}
</script>
<template>
<DocumentViewer ref="viewer" source="/sample.pdf" wasm-url="/pdfium.wasm" />
<button @click="exportAnnotations">Export</button>
</template>
See the Programmatic API page for the full method list.
Common features profiles
Three common feature profiles:
<!-- Read-only preview: zoom + scroll + search only -->
<DocumentViewer
source="/doc.pdf"
wasm-url="/pdfium.wasm"
:features="{ zoom: true, search: true, download: true }"
/>
<!-- Review workflow: annotations + threaded comments -->
<DocumentViewer
source="/doc.pdf"
wasm-url="/pdfium.wasm"
:features="{
zoom: true,
search: true,
outline: true,
thumbnails: true,
annotations: true,
commentThreads: true,
undoRedo: true,
download: true,
print: true,
}"
/>
<!-- Everything: kitchen-sink for an internal reader -->
<DocumentViewer
source="/doc.pdf"
wasm-url="/pdfium.wasm"
:features="{
zoom: true,
rotate: true,
spread: true,
pan: true,
fullscreen: true,
search: true,
selection: true,
outline: true,
thumbnails: true,
print: true,
download: true,
annotations: true,
commentThreads: true,
undoRedo: true,
keyboardShortcuts: true,
touchGestures: true,
}"
/>
See Features for the full flag table.
Next steps
- Features — every
featuresflag and itsfeatureConfig. - Annotations — annotation data model, creating highlights, threaded comments.
- Programmatic API — full method reference.
- Use cases — runnable demos for the common patterns.
- Bundle & Perf — chunking, WASM hosting, expected sizes per feature profile.