VUEjs v2 PDF viewer based on Mozilla's PDFJS.
100% PDFJS functionality:
- zoom
- open
- print
- download
- rotate
- text selection
- search panel
- pdf document password
- thumbnail, outline, attachments, annotation layers
Easily localized configurable panel
Cross-browser support (including IE11)
Color customization (IE11 not supported)
Buttons icons customization
Light/dark themes
Built-in typescript support
UMD/Unpkg support:
File | Size | Gzipped |
---|
vue-pdf-app.umd.min.js | 1742.89 KiB | 478.86 KiB |
vue-pdf-app.umd.js | 3115.59 KiB | 677.87 KiB |
vue-pdf-app.common.js | 3115.12 KiB | 677.71 KiB |
icons/main.css | 15 - 40 KiB (depends from browser) | |
Example
<template>
<vue-pdf-app pdf="http://example.com/sample.pdf"></vue-pdf-app>
</template>
<script>
import VuePdfApp from "vue-pdf-app";
// import this to use default icons for buttons
import "vue-pdf-app/dist/icons/main.css";
export default {
components: {
VuePdfApp
}
};
</script>
Live demo
Live demo 2
Examples source code
FAQ
API
:pdf
- Type:
string | null | ArrayBuffer | TypedArray
- Required:
false
- Usage:
<vue-pdf-app pdf="https://example.com/sample.pdf" />
<vue-pdf-app :pdf="ArrayBuffer" />
:title
- Description:
true
renames document title to pdf file name - Type: boolean
- Required: false
- Default: false
- Usage:
<vue-pdf-app :title="true" />
:theme.sync
- Type:
"dark" | "light"
- Required:
false
- Usage:
<vue-pdf-app theme="dark" />
<vue-pdf-app :theme="theme" />
<vue-pdf-app :theme.sync="theme" />
:config
- Description: toolbar configuration. Toolbar is available by default. Specify
false
for buttons or whole group of buttons to disable them. - Type: toolbar config (see below)
- Required:
false
- Default: toolbar config
- Usage:
<vue-pdf-app :config="config" />
<script>
export default {
data() {
return {
// disable "Previous page" button
config: {
toolbar: {
toolbarViewerLeft: {
previous: false
}
}
},
// disable whole page navigation panel
config2: {
toolbar: {
toolbarViewerLeft: false
}
},
// disable whole panel
config3: {
toolbar: false
}
};
}
};
</script>
Config specification
{
sidebar: {
viewThumbnail: true,
viewOutline: true,
viewAttachments: true,
},
secondaryToolbar: {
secondaryPresentationMode: true,
secondaryOpenFile: true,
secondaryPrint: true,
secondaryDownload: true,
secondaryViewBookmark: true,
firstPage: true,
lastPage: true,
pageRotateCw: true,
pageRotateCcw: true,
cursorSelectTool: true,
cursorHandTool: true,
scrollVertical: true,
scrollHorizontal: true,
scrollWrapped: true,
spreadNone: true,
spreadOdd: true,
spreadEven: true,
documentProperties: true,
},
toolbar: {
toolbarViewerLeft: {
findbar: true,
previous: true,
next: true,
pageNumber: true,
},
toolbarViewerRight: {
presentationMode: true,
openFile: true,
print: true,
download: true,
viewBookmark: true,
},
toolbarViewerMiddle: {
zoomOut: true,
zoomIn: true,
scaleSelectContainer: true,
},
},
errorWrapper: true,
};
@after-created(PDFViewerApplication)
- Description: emitted only once when Pdfjs library is binded to vue component. Can be used to set Pdfjs config before pdf document opening.
- Arguments:
- Usage:
<vue-pdf-app @after-created="afterCreated" />
@open(PDFViewerApplication)
- Description: emitted when pdf is opened but pages are not rendered.
- Arguments:
- Usage:
<vue-pdf-app @open="openHandler" />
@pages-rendered(PDFViewerApplication)
- Description: emitted when pdf document pages are rendered. Can be used to set default pages scale, for instance.
- Arguments:
- Usage:
<vue-pdf-app @pages-rendered="pagesRendered" />
<script>
export default {
methods: {
pagesRendered(pdfApp) {
setTimeout(() => (pdfApp.pdfViewer.currentScaleValue = "page-height"));
}
}
};
</script>
ℹ️ Events are triggered in the following order after-created (once) => open => pages-rendered
Slots
Slot name | Slot props | Prop type | Description |
---|
toolbar-left-prepend
toolbar-left-append
toolbar-left-append
toolbar-middle-prepend
toolbar-middle-append
toolbar-right-prepend
toolbar-right-append
toolbar-sidebar-prepend
toolbar-sidebar-append
secondary-toolbar-prepend
secondary-toolbar-append
footer
| toggleTheme | function() | Toggle theme |
<vue-pdf-app>
<template #toolbar-left-prepend="{ toggleTheme }">
<button @click="toggleTheme" type="button">Toggle theme</button>
</template>
</vue-pdf-app>
Color customization (IE11 not supported)
Colors of the pdf viewer are customized via custom css properties:
<style>
.pdf-app.dark {
--pdf-toolbar-color: black;
}
.pdf-app.light {
--pdf-toolbar-color: white;
}
</style>
Custom css properties specification
Property | Applied to selectors | Description |
---|
--pdf-app-background-color | .pdf-app | Background color for root pdf container |
--pdf-button-hover-font-color |
.pdf-app .toolbarButton:hover
.pdf-app .toolbarButton:focus
.pdf-app .dropdownToolbarButton:hover
.pdf-app .secondaryToolbarButton:hover
.pdf-app .secondaryToolbarButton:focus
| Hover color for buttons of toolbar and secondary toolbar |
--pdf-button-toggled-color |
.pdf-app .toolbarButton.toggled
.pdf-app .splitToolbarButton.toggled > .toolbarButton.toggled
.pdf-app .secondaryToolbarButton.toggled
.pdf-app .outlineItemToggler:hover
.pdf-app .outlineItemToggler:hover + a
.pdf-app .outlineItemToggler:hover ~ .outlineItems
.pdf-app .outlineItem > a:hover
.pdf-app .attachmentsItem > button:hover
|
Background color for toggleable buttons when selected, outline items on hover, attachment items on hover
|
--pdf-dialog-button-color | .pdf-app .dialog .overlayButton |
|
--pdf-dialog-button-font-color | .pdf-app .dialog .overlayButton |
|
--pdf-error-more-info-color | .pdf-app #errorMoreInfo |
|
--pdf-error-more-info-font-color | .pdf-app #errorMoreInfo |
|
--pdf-error-wrapper-color | .pdf-app #errorWrapper |
|
--pdf-find-input-placeholder-font-color | .pdf-app #findInput::placeholder |
|
--pdf-find-message-font-color | .pdf-app #findMsg |
|
--pdf-find-results-count-color | .pdf-app #findResultsCount |
|
--pdf-find-results-count-font-color | .pdf-app #findResultsCount |
|
--pdf-horizontal-toolbar-separator-color | .pdf-app .horizontalToolbarSeparator |
|
--pdf-input-color | .pdf-app .toolbarField |
|
--pdf-input-font-color | .pdf-app .toolbarField |
|
--pdf-loading-bar-color | .pdf-app #loadingBar .progress |
|
--pdf-loading-bar-secondary-color | .pdf-app #loadingBar .progress.indeterminate .glimmer |
|
--pdf-not-found-color | .pdf-app #findInput.notFound |
|
--pdf-overlay-container-color | .pdf-app #overlayContainer | Background color for overlay container of dialogs |
--pdf-overlay-container-dialog-color | .pdf-app #overlayContainer > .container > .dialog |
Background color for document properties, password, print dialogs
|
--pdf-overlay-container-dialog-font-color | .pdf-app #overlayContainer > .container > .dialog |
Font color for document properties, password, print dialogs
|
--pdf-overlay-container-dialog-separator-color | .pdf-app .dialog .separator |
|
--pdf-sidebar-content-color | .pdf-app #sidebarContent |
Background color for sidebar
|
--pdf-split-toolbar-button-separator-color |
.pdf-app .splitToolbarButtonSeparator
.pdf-app .verticalToolbarSeparator
|
|
--pdf-thumbnail-selection-ring-selected-color | .pdf-app .thumbnail.selected > .thumbnailSelectionRing |
Border color for selected thumbnail
|
--pdf-thumbnail-selection-ring-color |
.pdf-app a:focus > .thumbnail > .thumbnailSelectionRing
.pdf-app .thumbnail:hover > .thumbnailSelectionRing
|
Border color for thumbnail on hover and focus
|
--pdf-toolbar-color |
.pdf-app #toolbarContainer
.pdf-app .findbar
.pdf-app .secondaryToolbar
.pdf-app .doorHanger:after
.pdf-app .doorHangerRight:after
.pdf-app .dropdownToolbarButton > select
.pdf-app .dropdownToolbarButton > select > option
|
Background color for toolbar, findbar, secondary toolbar, page scale dropdown
|
--pdf-toolbar-font-color |
.pdf-app .toolbarButton
.pdf-app .dropdownToolbarButton
.pdf-app .secondaryToolbarButton
.pdf-app .dropdownToolbarButton > select
.pdf-app .toolbarLabel
.pdf-app .outlineItem > a
.pdf-app .attachmentsItem > button
|
Font color for toolbar, findbar, secondary toolbar, page scale dropdown, attachments name |
--pdf-toolbar-sidebar-color | .pdf-app #toolbarSidebar |
|
Icons customization
To use default icons import "vue-pdf-app/dist/icons/main.css";
.
To use custom icons you have to implement icons.css:
.vue-pdf-app-icon::before,
.vue-pdf-app-icon::after {
font-family: "your font family";
}
.vue-pdf-app-icon.zoom-out::before {
content: "icon code";
}
Light/dark themes
Algorithm of theme apply
Toggle theme button is not implemented by default.
It's up to you to decide where to place it.
The button can be implemented with slots:
<vue-pdf-app>
<template #footer="{ toggleTheme }">
<button @click="toggleTheme" type="button">Toggle theme</button>
</template>
</vue-pdf-app>
Localized panel
English is the default language for panel.
Use <link rel="resource" type="application/l10n" href="path-to-localization-file">
in your html for localization.
See localization file examples.
Examples
Script tag (unpkg)
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="utf-8" />
<title>Vue-pdf-app demo</title>
<link
rel="stylesheet"
href="https://unpkg.com/vue-pdf-app@2.0.0/dist/icons/main.css"
/>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vue-pdf-app@2.0.0"></script>
</head>
<body>
<div id="app" style="height: 100%;">
<vue-pdf-app pdf="/sample.pdf"></vue-pdf-app>
</div>
<script>
new Vue({
components: {
PdfApp: window["vue-pdf-app"]
}
}).$mount("#app");
</script>
</body>
</html>
Typescript
<template>
<div id="app">
<vue-pdf-app pdf="/sample.pdf"></vue-pdf-app>
</div>
</template>
<script lang="ts">
import "vue-pdf-app/dist/icons/main.css";
import VuePdfApp from "vue-pdf-app";
import { Component, Vue } from "vue-property-decorator";
@Component({
components: {
VuePdfApp
}
})
export default class App extends Vue {}
</script>
Lazy loading
PDFJS is a huge package (see the library size table above).
So use lazy loading to split your bundle into small pieces.
<template>
<div id="app">
<vue-pdf-app></vue-pdf-app>
</div>
</template>
<script>
import "vue-pdf-app/dist/icons/main.css";
import Loader from "./components/Loader.vue";
export default {
name: "App",
components: {
"vue-pdf-app": () => ({
component: new Promise((res) => {
return setTimeout(
() => res(import(/* webpackChunkName: "pdf-viewer" */ "vue-pdf-app")),
4000
);
}),
loading: Loader
})
}
};
</script>
PDFJS interaction
You can interact with pdfjs library when pdf is opened via open
event.
<template>
<div id="app">
<div id="pdf-wrapper">
<vue-pdf-app pdf="/sample.pdf" @open="openHandler"></vue-pdf-app>
</div>
<div id="info">
<h1>PDF info:</h1>
<div v-for="item in info" :key="item.name">
<span>{{ item.name }}: {{ item.value }}</span>
<br />
</div>
</div>
</div>
</template>
<script>
import "vue-pdf-app/dist/icons/main.css";
import VuePdfApp from "vue-pdf-app";
export default {
name: "App",
components: {
VuePdfApp
},
data() {
return {
info: []
};
},
methods: {
async openHandler(pdfApp) {
this.info = [];
const info = await pdfApp.pdfDocument
.getMetadata()
.catch(console.error.bind(console));
if (!info) return;
const props = Object.keys(info.info);
props.forEach((prop) => {
const obj = {
name: prop,
value: info.info[prop]
};
this.info.push(obj);
});
}
}
};
</script>