npm.io
0.1.5 • Published 2d ago

v-file-preview

Licence
MIT
Version
0.1.5
Deps
11
Size
5.7 MB
Vulns
0
Weekly
0

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.

Features

  • PDF — Rendered with pdfjs-dist. Built-in toolbar with pagination, zoom, fullscreen, and download.
  • DOCX — Rendered via @vue-office/docx.
  • Excel / CSV — Rendered via @vue-office/excel (.xlsx, .xls, .csv).
  • Images — Native <img> tag (.jpg, .jpeg, .png, .webp, .gif, .svg).
  • Video — Native <video> tag (.mp4, .webm, .ogg, .mov).
  • Audio — Native <audio> tag (.mp3, .wav).
  • Code / Text — Syntax-highlighted with CodeMirror (.json, .js, .ts, .vue, .html, .css, .txt, .md).
  • Download protection — Optionally disable right-click save and the browser download button.
  • KeepAlive caching — Switching between files doesn't re-render previously loaded previews.
  • Vue 3 plugin — Register globally or import the component locally.
  • TypeScript — Full type definitions included out of the box.
  • SSR-safe entry — Preview engines load only after browser mount, with stable server fallback markup.

Installation

npm
npm install v-file-preview
yarn
yarn add v-file-preview
pnpm
pnpm add v-file-preview

Don't forget to follow me on GitHub!


Quick Start

Global Registration (Plugin)
// 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>

Usage Examples

Preview a File from URL
<template>
	<VFileViewer
		url="https://example.com/document.pdf"
		name="document.pdf"
		width="100%"
		height="600px" />
</template>
Preview a File / Blob Object
<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>
Disable Download
<template>
	<VFileViewer
		url="/confidential-report.pdf"
		name="report.pdf"
		:can-download="false" />
</template>
Handle Events
<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>

Props

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):

  1. file.name (if file is a File with a name)
  2. The name prop
  3. The pathname of the url

The extracted extension is then matched against the built-in extension map.


Events

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 Composable

A 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()

Supported File Types

Category Extensions Viewer Engine
PDF .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

CSS Customization

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;
}
Internal CSS Classes Reference

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 .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>

TypeScript

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'

License

MIT Safdar Azeem