secure-pdf-viewer-vue3
v1.0.0
Published
Secure PDF viewer for Vue 3 - Canvas-only rendering prevents XSS attacks from malicious PDFs
Downloads
100
Maintainers
Readme
secure-pdf-viewer-vue3
A secure PDF viewer component for Vue 3. Uses canvas-only rendering to prevent XSS attacks from malicious PDF files.
Features
- Canvas-only rendering -- PDF pages are rasterized to
<canvas>, notextLayerorannotationLayerDOM elements are created, eliminating all XSS injection vectors - JavaScript execution disabled --
isEvalSupported: falseprevents PDF.js from executing embedded JavaScript - External resource blocking --
disableAutoFetch: trueblocks external resource loading (SSRF prevention) - Font injection prevention --
disableFontFace: trueblocks@font-faceinjection - Built-in toolbar with page navigation and zoom controls
- Keyboard shortcuts support
- Three input modes: URL, File object, and ArrayBuffer
- TypeScript support
Installation
npm install secure-pdf-viewer-vue3 pdfjs-distBasic Usage
Load PDF from URL
<template>
<SecurePdfViewer src="https://example.com/document.pdf" />
</template>
<script setup>
import { SecurePdfViewer } from 'secure-pdf-viewer-vue3';
</script>Load PDF from File Upload
<template>
<div>
<input type="file" accept=".pdf" @change="onFileChange" />
<SecurePdfViewer v-if="pdfFile" :file="pdfFile" />
</div>
</template>
<script setup>
import { ref } from 'vue';
import { SecurePdfViewer } from 'secure-pdf-viewer-vue3';
const pdfFile = ref(null);
function onFileChange(e) {
pdfFile.value = e.target.files[0];
}
</script>Load PDF from ArrayBuffer
<template>
<SecurePdfViewer v-if="pdfData" :data="pdfData" />
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { SecurePdfViewer } from 'secure-pdf-viewer-vue3';
const pdfData = ref(null);
onMounted(async () => {
const response = await fetch('/document.pdf');
pdfData.value = await response.arrayBuffer();
});
</script>Full Example
<template>
<SecurePdfViewer
ref="viewerRef"
src="/docs/report.pdf"
:initial-scale="1.5"
:show-toolbar="true"
worker-src="/pdf.worker.min.mjs"
@page-change="onPageChange"
@scale-change="onScaleChange"
@load-state-change="onLoadStateChange"
@error="onError"
/>
</template>
<script setup>
import { ref } from 'vue';
import { SecurePdfViewer } from 'secure-pdf-viewer-vue3';
const viewerRef = ref(null);
function onPageChange(page, totalPages) {
console.log(`Page ${page} of ${totalPages}`);
}
function onScaleChange(scale) {
console.log(`Zoom: ${Math.round(scale * 100)}%`);
}
function onLoadStateChange(state) {
console.log(`Load state: ${state}`);
}
function onError(error) {
console.error('PDF error:', error);
}
// Access exposed methods via ref
function jumpToPage5() {
viewerRef.value?.goToPage(5);
}
</script>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| src | string | undefined | URL of the PDF file |
| file | File | undefined | File object (for file upload scenarios) |
| data | ArrayBuffer \| Uint8Array | undefined | Raw PDF data |
| initialScale | number | 1.0 | Initial zoom scale |
| minScale | number | 0.25 | Minimum zoom scale |
| maxScale | number | 5.0 | Maximum zoom scale |
| showToolbar | boolean | true | Whether to show the toolbar |
| class | string | '' | Custom CSS class for the container |
| style | object | {} | Custom inline styles for the container |
| workerSrc | string | undefined | Custom path to the PDF.js worker file |
| pixelRatio | number | window.devicePixelRatio | Device pixel ratio for rendering |
| disableDownload | boolean | false | Disable the download button in toolbar |
Events
| Event | Payload | Description |
|-------|---------|-------------|
| load-state-change | state: 'idle' \| 'loading' \| 'ready' \| 'error' | Fired when the loading state changes |
| page-change | page: number, totalPages: number | Fired when the current page changes |
| scale-change | scale: number | Fired when the zoom scale changes |
| error | error: Error | Fired when an error occurs |
Exposed Methods
Access these methods via a template ref:
| Method | Signature | Description |
|--------|-----------|-------------|
| goToPage | (page: number) => void | Navigate to a specific page |
| setScale | (scale: number) => void | Set the zoom scale (clamped to min/max) |
| getState | () => { currentPage, totalPages, scale } | Get the current viewer state |
Keyboard Shortcuts
When the viewer is focused:
| Key | Action |
|-----|--------|
| Arrow Left / Arrow Up | Previous page |
| Arrow Right / Arrow Down | Next page |
| Ctrl + | Zoom in |
| Ctrl - | Zoom out |
Security Features
This component is designed with security as the core principle:
No DOM injection -- PDF content is rendered purely to a
<canvas>element. NoinnerHTML,textLayer, orannotationLayeris used, which eliminates all XSS attack vectors from malicious PDFs.JavaScript execution disabled -- The
isEvalSupported: falseconfiguration prevents PDF.js from executing any JavaScript embedded in PDF files.External resource blocking --
disableAutoFetch: trueprevents the PDF from loading external resources, mitigating SSRF attacks.Font injection prevention --
disableFontFace: trueblocks@font-faceCSS injection from PDF fonts.
Worker Setup for Production
For production deployments with strict CSP (Content Security Policy), place the pdf.worker.min.mjs file in your public directory and provide its path via the workerSrc prop:
<SecurePdfViewer
src="/document.pdf"
worker-src="/pdf.worker.min.mjs"
/>