Universal document viewer for PDF and PPTX files
npm install @docmentis/udoc-viewerEmbedded document viewer and headless document parsing/rendering API, powered by WebAssembly.
Free. Unlimited. Forever. Provided by docMentis.com.
| Format | Extensions | Notes |
|--------|------------|-------|
| PDF | .pdf | |
| PPTX | .pptx | Early stage - shapes, text, images, gradients supported |
| Images | .jpg, .jpeg, .png, .gif, .bmp, .tif, .tiff, .webp, .ico, .tga, .ppm, .pgm, .pbm, .hdr, .exr, .qoi | Multi-page TIFF supported |
``bash`
npm install @docmentis/udoc-viewer
`typescript
import { UDocClient } from '@docmentis/udoc-viewer';
// Create a client (loads the WASM engine)
const client = await UDocClient.create();
// Create a viewer attached to a container element
const viewer = await client.createViewer({
container: '#viewer'
});
// Load a document
await viewer.load('https://example.com/document.pdf');
// Clean up when done
viewer.destroy();
client.destroy();
`
The viewer accepts multiple document sources:
`typescript
// From URL
await viewer.load('https://example.com/document.pdf');
// From File object (e.g., from file input)
await viewer.load(file);
// From raw bytes
await viewer.load(new Uint8Array(buffer));
// Close current document
viewer.close();
`
`typescript`
const client = await UDocClient.create({
// Custom base URL for worker and WASM files (optional)
baseUrl: 'https://cdn.example.com/udoc/',
});
`typescript
const viewer = await client.createViewer({
// Container element or CSS selector (required for UI mode)
container: '#viewer',
// Scroll mode: 'continuous' or 'single-page'
scrollMode: ScrollMode.Continuous,
// Layout mode: 'single-page', 'two-page', 'two-page-cover'
layoutMode: LayoutMode.SinglePage,
// Zoom mode: 'fit-width', 'fit-page', 'fit-height', 'actual-size', 'custom'
zoomMode: ZoomMode.FitSpreadWidth,
// Initial zoom level (when zoomMode is 'custom')
zoom: 1,
// Custom zoom steps for zoom in/out
zoomSteps: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 3, 4],
// Spacing between pages in pixels
pageSpacing: 10,
// Initially active panel: 'thumbnails', 'outline', or null
activePanel: null,
// Target display DPI (default: 96)
dpi: 96,
});
`
`typescript
// Get current page (1-based)
const page = viewer.currentPage;
// Go to a specific page
viewer.goToPage(5);
// Navigate to a destination (from outline)
viewer.goToDestination(destination);
`
`typescript
// Check if document is loaded
if (viewer.isLoaded) {
// Get page count
const total = viewer.pageCount;
// Get page dimensions (0-based index)
const info = await viewer.getPageInfo(0);
console.log(Page 1: ${info.width} x ${info.height} points);
// Get document outline (table of contents)
const outline = await viewer.getOutline();
// Get annotations on a page
const annotations = await viewer.getPageAnnotations(0);
}
`
Render pages to images without UI:
`typescript
// Create headless viewer (no container)
const viewer = await client.createViewer();
await viewer.load(pdfBytes);
// Render page to ImageData
const imageData = await viewer.renderPage(0, { scale: 2 });
// Render to Blob
const blob = await viewer.renderPage(0, {
format: 'blob',
imageType: 'image/png'
});
// Render to data URL
const dataUrl = await viewer.renderPage(0, {
format: 'data-url',
imageType: 'image/jpeg',
quality: 0.9
});
`
Compose new documents by cherry-picking and rotating pages:
`typescript
// Create a new document from pages of existing documents
const [newDoc] = await client.compose([
[
{ doc: viewerA, pages: "1-3" },
{ doc: viewerB, pages: "5", rotation: 90 }
]
]);
// Export the composed document
const bytes = await newDoc.toBytes();
await newDoc.download('composed.pdf');
`
`typescriptLoaded ${pageCount} pages
// Document loaded
const unsubscribe = viewer.on('document:load', ({ pageCount }) => {
console.log();
});
// Document closed
viewer.on('document:close', () => {
console.log('Document closed');
});
// Error occurred
viewer.on('error', ({ error, phase }) => {
console.error(Error during ${phase}:, error);
});
// Unsubscribe
unsubscribe();
``
MIT