
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
v-file-preview
Advanced tools
Preview PDFs, Word documents, Excel spreadsheets, images, videos, audio, and code/text files — all from a single component. Just pass a URL or a File/Blob object and v-file-preview picks the right viewer automatically.
pdfjs-dist. Built-in toolbar with pagination, zoom, fullscreen, and download.@vue-office/docx.@vue-office/excel (.xlsx, .xls, .csv).<img> tag (.jpg, .jpeg, .png, .webp, .gif, .svg).<video> tag (.mp4, .webm, .ogg, .mov).<audio> tag (.mp3, .wav)..json, .js, .ts, .vue, .html, .css, .txt, .md).npm install v-file-preview
yarn add v-file-preview
pnpm add v-file-preview
Don't forget to follow me on GitHub!
// main.ts
import { createApp } from 'vue'
import VFileViewerPlugin from 'v-file-preview'
import App from './App.vue'
const app = createApp(App)
app.use(VFileViewerPlugin) // registers <VFileViewer> globally
app.mount('#app')
<script setup lang="ts">
import { VFileViewer } from 'v-file-preview'
</script>
<template>
<VFileViewer
url="https://example.com/sample.pdf"
name="report.pdf" />
</template>
<template>
<VFileViewer
url="https://example.com/document.pdf"
name="document.pdf"
width="100%"
height="600px" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { VFileViewer } from 'v-file-preview'
const selectedFile = ref<File | null>(null)
const onFileChange = (e: Event) => {
const input = e.target as HTMLInputElement
selectedFile.value = input.files?.[0] ?? null
}
</script>
<template>
<input
type="file"
@change="onFileChange" />
<VFileViewer
v-if="selectedFile"
:file="selectedFile"
:name="selectedFile.name" />
</template>
<template>
<VFileViewer
url="/confidential-report.pdf"
name="report.pdf"
:can-download="false" />
</template>
<script setup lang="ts">
import { VFileViewer, useViewer } from 'v-file-preview'
const {
isLoading,
isError,
errorMessage,
handleLoadStart,
handleLoadSuccess,
handleLoadError,
} = useViewer()
</script>
<template>
<p v-if="isLoading">Loading preview…</p>
<p
v-if="isError"
style="color: red;">
{{ errorMessage }}
</p>
<VFileViewer
url="/presentation.docx"
name="presentation.docx"
@rendered="handleLoadSuccess"
@error="handleLoadError" />
</template>
| Prop | Type | Default | Description |
|---|---|---|---|
file | File | Blob | null | undefined | A File or Blob object to preview. Takes priority over url. |
url | string | null | undefined | A URL pointing to the file to preview. |
name | string | null | undefined | An explicit file name (with extension) used to determine the file type when it can't be inferred from the file or url. |
width | string | '100%' | CSS width of the viewer wrapper. |
height | string | '100%' | CSS height of the viewer wrapper. |
canDownload | boolean | true | When false, disables right-click saving (images/PDFs), hides the download button (PDFs), and removes the browser download control (video/audio). |
How is the file type detected?
The extension is extracted from (in order of priority):
file.name(iffileis aFilewith a name)- The
nameprop- The pathname of the
urlThe extracted extension is then matched against the built-in extension map.
| Event | Payload | Description |
|---|---|---|
rendered | — | Emitted when the file has been successfully loaded and rendered. |
error | Error | Emitted when loading or rendering fails. The payload is an Error object with a descriptive message. |
useViewer ComposableA convenience composable that provides reactive loading/error state for pairing with VFileViewer events.
import { useViewer } from 'v-file-preview'
const {
isLoading, // Ref<boolean>
isError, // Ref<boolean>
errorMessage, // Ref<string>
handleLoadStart, // () => void — call when switching files
handleLoadSuccess, // () => void — bind to @rendered
handleLoadError, // (err: Error) => void — bind to @error
} = useViewer()
| Category | Extensions | Viewer Engine |
|---|---|---|
.pdf | pdfjs-dist — custom canvas renderer with pagination, zoom, fullscreen | |
| Word | .docx | @vue-office/docx |
| Spreadsheet | .xlsx, .xls, .csv | @vue-office/excel |
| Image | .jpg, .jpeg, .png, .webp, .gif, .svg | Native <img> |
| Video | .mp4, .webm, .ogg, .mov | Native <video> |
| Audio | .mp3, .wav | Native <audio> |
| Code / Text | .json, .js, .ts, .vue, .html, .css, .txt, .md | CodeMirror 6 (read-only) |
| Unknown | everything else | Friendly "unsupported" placeholder |
The wrapper element uses the class v-file-preview-wrapper. You can override its styles to match your design system:
/* Override the wrapper border, radius, and background */
.v-file-preview-wrapper {
border-radius: 12px;
border: 1px solid #d1d5db;
background-color: #fafafa;
}
Each sub-viewer exposes scoped CSS classes. Because they are scoped, target them through the wrapper using :deep() if you need fine-grained control.
| Viewer | Key Classes | Description |
|---|---|---|
.pdf-viewer-container, .pdf-toolbar, .toolbar-btn, .pdf-canvas-wrapper, .pdf-canvas | PDF viewer layout, toolbar buttons, and canvas | |
| Office | .office-viewer-container | DOCX / Excel container |
| Image | .image-viewer-container, .image-content | Image wrapper and the <img> element |
| Media | .media-viewer-container, .media-video, .media-audio | Video & audio wrapper and elements |
| Code | .code-viewer-container, .cm-wrapper | Code viewer and CodeMirror wrapper |
| Unsupported | .unsupported-container, .icon-wrapper, .title, .subtitle | Unsupported file fallback UI |
Example — customizing the PDF toolbar:
<style>
.v-file-preview-wrapper :deep(.pdf-toolbar) {
background-color: #1f2937;
color: #f9fafb;
}
.v-file-preview-wrapper :deep(.toolbar-btn) {
color: #d1d5db;
}
.v-file-preview-wrapper :deep(.toolbar-btn:hover:not(:disabled)) {
background-color: #374151;
color: #ffffff;
}
</style>
Example — dark theme for the image viewer:
<style>
.v-file-preview-wrapper :deep(.image-viewer-container) {
background-color: #111827;
}
</style>
All public types are exported and available for direct import:
import type { VFileViewerProps } from 'v-file-preview'
import { FileCategory } from 'v-file-preview'
// FileCategory enum values
FileCategory.PDF // 'pdf'
FileCategory.DOCX // 'docx'
FileCategory.EXCEL // 'excel'
FileCategory.IMAGE // 'image'
FileCategory.VIDEO // 'video'
FileCategory.AUDIO // 'audio'
FileCategory.CODE // 'code'
FileCategory.UNKNOWN // 'unknown'
FAQs
Production ready file viewer for Vue 3
The npm package v-file-preview receives a total of 82 weekly downloads. As such, v-file-preview popularity was classified as not popular.
We found that v-file-preview demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.