New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@files-preview-app/preview-file

Package Overview
Dependencies
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@files-preview-app/preview-file

Universal file preview library for Web, React, Angular, and Vue. 100% client-side with zero cloud dependency. Preview PDF, Word, Excel, PowerPoint, CSV, ZIP, Markdown, 3D Models (STL/OBJ), Images, Video, Audio, and Code with built-in toolbar.

latest
Source
npmnpm
Version
1.3.20
Version published
Weekly downloads
0
Maintainers
1
Weekly downloads
Ā 
Created
Source

@files-preview-app/preview-file

Live Demo npm version License: MIT GitHub

The all-in-one, 100% client-side file preview library for React, Next.js, Angular, Vue 3, Nuxt 3, and Vanilla JavaScript / TypeScript.
Preview PDF, Word (.docx), Excel (.xlsx), PowerPoint (.pptx), CSV/TSV, ZIP Archives, Rich Markdown, 3D Models (.stl, .obj), Images, Video, Audio, and Code/Text (190+ languages) with a built-in customizable toolbar (zoom, rotate, thumbnails, page jump, download, print). 100% free, permissive open-source, and client-side (zero cloud or server needed).

🌐 Live Interactive Demo

Try the interactive demo with instant sample files directly in your browser:
šŸ‘‰ Launch Live Demo (GitHub Pages)

  • Instant samples for PDF, DOCX, XLSX, PPTX, CSV, ZIP, Markdown, 3D STL, SVG, and Code
  • Drag-and-drop your own files from your computer
  • Live framework code generator (React, Angular, Vue, Vanilla)
  • Light & Dark mode toggle

šŸ“¦ Installation

Install the single all-in-one package in your project:

npm install @files-preview-app/preview-file

Or using Yarn, pnpm, or Bun:

pnpm add @files-preview-app/preview-file
# or
yarn add @files-preview-app/preview-file
# or
bun add @files-preview-app/preview-file

Import the toolbar and viewer stylesheet in your global CSS or root component:

import '@files-preview-app/preview-file/styles.css';

šŸŽÆ Supported Frameworks & Version Matrix

FrameworkSupported VersionsPackage Entry PointIntegration Notes
React>=16.8.0 (React 17, 18, 19)@files-preview-app/preview-file/reactFull Hooks, forwardRef, FilePreviewHandle
Next.js13.x, 14.x, 15.x@files-preview-app/preview-file/reactApp Router ('use client') & Pages Router
Angular>=14.0.0 (Angular 15, 16, 17, 18, 19)@files-preview-app/preview-file/angularStandalone Component & NgModule, @ViewChild
Vue 3>=3.0.0 (Vue 3.2, 3.3, 3.4, 3.5+)@files-preview-app/preview-file/vueComposition API (<script setup>) & Options API
Nuxt 3>=3.0.0@files-preview-app/preview-file/vueWrapped inside <ClientOnly> component
Vanilla JS / TSES2020+@files-preview-app/preview-filePure DOM API, Vite, Webpack, Rollup, Parcel, esbuild
Svelte / SolidAll versions@files-preview-app/preview-fileDirect DOM container attachment

šŸš€ Framework Integration Guides

1. React (@files-preview-app/preview-file/react)

Basic Usage

import React, { useState } from 'react';
import { FilePreview } from '@files-preview-app/preview-file/react';
import '@files-preview-app/preview-file/styles.css';

export default function App() {
  const [file, setFile] = useState<File | string>(
    'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf'
  );

  return (
    <div style={{ padding: '20px' }}>
      <input
        type="file"
        onChange={(e) => e.target.files?.[0] && setFile(e.target.files[0])}
      />

      <div style={{ width: '100%', height: '750px', marginTop: '16px' }}>
        <FilePreview
          src={file}
          options={{
            theme: 'light', // 'light' | 'dark' | 'auto'
            showToolbar: true,
            toolbarPosition: 'top', // 'top' | 'bottom'
            showThumbnails: false,
          }}
          onLoading={() => console.log('File loading started')}
          onLoaded={(info) => console.log('Loaded successfully:', info)}
          onError={(err) => console.error('Preview error:', err)}
          onPageChange={(data) => console.log('Page switched:', data)}
          onZoomChange={(data) => console.log('Zoom scale:', data)}
        />
      </div>
    </div>
  );
}

Advanced React (Programmatic Controls via ref)

import React, { useRef, useState } from 'react';
import { FilePreview, type FilePreviewHandle } from '@files-preview-app/preview-file/react';
import '@files-preview-app/preview-file/styles.css';

export default function AdvancedViewer() {
  const previewRef = useRef<FilePreviewHandle>(null);
  const [currentPage, setCurrentPage] = useState(1);
  const [file, setFile] = useState<string>('https://example.com/contract.docx');

  // Trigger instance methods programmatically
  const handleZoomIn = () => previewRef.current?.getInstance()?.zoomIn?.();
  const handleZoomOut = () => previewRef.current?.getInstance()?.zoomOut?.();
  const handleRotate = () => previewRef.current?.getInstance()?.rotateCW?.();
  const handleDownload = () => previewRef.current?.getInstance()?.download?.();
  const handlePrint = () => previewRef.current?.getInstance()?.print?.();
  const handleNextPage = () => {
    const next = currentPage + 1;
    previewRef.current?.getInstance()?.goToPage?.(next);
  };

  return (
    <div>
      {/* Custom external controls */}
      <div style={{ display: 'flex', gap: '8px', marginBottom: '12px' }}>
        <button onClick={handleZoomIn}>Zoom In (+)</button>
        <button onClick={handleZoomOut}>Zoom Out (-)</button>
        <button onClick={handleRotate}>Rotate (90°)</button>
        <button onClick={handleNextPage}>Next Page</button>
        <button onClick={handleDownload}>Download File</button>
        <button onClick={handlePrint}>Print</button>
      </div>

      <div style={{ width: '100%', height: '800px' }}>
        <FilePreview
          ref={previewRef}
          src={file}
          options={{ theme: 'light', showToolbar: true }}
          onPageChange={(data: any) => setCurrentPage(data.page)}
        />
      </div>
    </div>
  );
}

2. Next.js (App Router & Pages Router)

Because file previews use client-side DOM and canvas APIs, disable SSR using Next.js dynamic:

'use client';

import dynamic from 'next/dynamic';
import '@files-preview-app/preview-file/styles.css';

// Disable SSR for the preview component
const FilePreview = dynamic(
  () => import('@files-preview-app/preview-file/react').then((mod) => mod.FilePreview),
  { ssr: false }
);

export default function NextPreviewPage() {
  return (
    <main style={{ width: '100vw', height: '100vh' }}>
      <FilePreview
        src="https://example.com/spreadsheet.xlsx"
        options={{ theme: 'auto', showToolbar: true }}
      />
    </main>
  );
}

3. Angular (@files-preview-app/preview-file/angular)

Standalone Component (Angular 14, 15, 16, 17, 18, 19)

import { Component, ViewChild } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FilePreviewComponent } from '@files-preview-app/preview-file/angular';

@Component({
  selector: 'app-document-viewer',
  standalone: true,
  imports: [CommonModule, FilePreviewComponent],
  template: `
    <div class="viewer-wrapper" style="width: 100%; height: 800px;">
      <!-- File Selector -->
      <input type="file" (change)="onFileChange($event)" />

      <!-- Custom Actions -->
      <div class="actions" style="margin: 10px 0;">
        <button (click)="zoomIn()">Zoom In</button>
        <button (click)="zoomOut()">Zoom Out</button>
        <button (click)="download()">Download</button>
      </div>

      <!-- Preview Component -->
      <fp-file-preview
        #preview
        [src]="selectedFile"
        [options]="{ theme: 'light', showToolbar: true, toolbarPosition: 'top' }"
        (loading)="onLoading()"
        (loaded)="onLoaded($event)"
        (error)="onError($event)"
        (pageChange)="onPageChange($event)"
        (zoomChange)="onZoomChange($event)"
      />
    </div>
  `,
  styleUrls: ['@files-preview-app/preview-file/styles.css']
})
export class DocumentViewerComponent {
  @ViewChild('preview') previewComponent!: FilePreviewComponent;

  selectedFile: string | File = 'https://example.com/presentation.pptx';

  onFileChange(event: Event) {
    const input = event.target as HTMLInputElement;
    if (input.files?.[0]) {
      this.selectedFile = input.files[0];
    }
  }

  // Programmatic controls
  zoomIn() {
    this.previewComponent.getInstance()?.zoomIn?.();
  }

  zoomOut() {
    this.previewComponent.getInstance()?.zoomOut?.();
  }

  download() {
    this.previewComponent.getInstance()?.download?.();
  }

  // Event handlers
  onLoading() {
    console.log('Loading file...');
  }

  onLoaded(event: unknown) {
    console.log('File successfully loaded:', event);
  }

  onError(err: Error) {
    console.error('Failed to preview file:', err);
  }

  onPageChange(data: unknown) {
    console.log('Page switched:', data);
  }

  onZoomChange(data: unknown) {
    console.log('Zoom changed:', data);
  }
}

Traditional NgModule (Angular 14+)

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FilePreviewComponent } from '@files-preview-app/preview-file/angular';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, FilePreviewComponent],
  bootstrap: [AppComponent]
})
export class AppModule {}

4. Vue 3 (@files-preview-app/preview-file/vue)

Composition API (<script setup>)

<template>
  <div class="preview-container" style="width: 100%; height: 800px;">
    <!-- Controls Bar -->
    <div class="toolbar-actions" style="margin-bottom: 12px; display: flex; gap: 8px;">
      <input type="file" @change="handleFileSelect" />
      <button @click="zoomIn">Zoom In (+)</button>
      <button @click="zoomOut">Zoom Out (-)</button>
      <button @click="rotate">Rotate (90°)</button>
      <button @click="download">Download</button>
    </div>

    <!-- Universal Preview Component -->
    <FilePreview
      ref="previewRef"
      :src="fileSource"
      :options="{
        theme: 'light',
        showToolbar: true,
        toolbarPosition: 'top'
      }"
      @loading="onLoading"
      @loaded="onLoaded"
      @error="onError"
      @page-change="onPageChange"
      @zoom-change="onZoomChange"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { FilePreview } from '@files-preview-app/preview-file/vue';
import '@files-preview-app/preview-file/styles.css';

const previewRef = ref<InstanceType<typeof FilePreview> | null>(null);
const fileSource = ref<string | File>('https://example.com/archive.zip');

function handleFileSelect(e: Event) {
  const target = e.target as HTMLInputElement;
  if (target.files?.[0]) {
    fileSource.value = target.files[0];
  }
}

// Programmatic methods
function zoomIn() {
  previewRef.value?.getInstance()?.zoomIn?.();
}

function zoomOut() {
  previewRef.value?.getInstance()?.zoomOut?.();
}

function rotate() {
  previewRef.value?.getInstance()?.rotateCW?.();
}

function download() {
  previewRef.value?.getInstance()?.download?.();
}

// Event callbacks
function onLoading() {
  console.log('Rendering file...');
}

function onLoaded(metadata: unknown) {
  console.log('Preview ready:', metadata);
}

function onError(err: unknown) {
  console.error('Preview error:', err);
}

function onPageChange(pageData: unknown) {
  console.log('Page switched:', pageData);
}

function onZoomChange(zoomData: unknown) {
  console.log('Zoom changed:', zoomData);
}
</script>

Nuxt 3 Integration

Wrap inside <ClientOnly> to avoid server-side rendering:

<template>
  <ClientOnly>
    <div style="height: 800px;">
      <FilePreview src="/documents/sample.pdf" />
    </div>
    <template #fallback>
      <div>Loading preview component...</div>
    </template>
  </ClientOnly>
</template>

<script setup lang="ts">
import { FilePreview } from '@files-preview-app/preview-file/vue';
import '@files-preview-app/preview-file/styles.css';
</script>

5. Vanilla JavaScript / TypeScript (@files-preview-app/preview-file)

Use directly with any build tool (Vite, Webpack, Rollup) or via <script type="module">:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Universal File Preview</title>
  <!-- Link Stylesheet -->
  <link rel="stylesheet" href="node_modules/@files-preview-app/preview-file/dist/styles.css" />
  <style>
    #viewer-container {
      width: 100%;
      height: 850px;
      border: 1px solid #e2e8f0;
      border-radius: 8px;
    }
  </style>
</head>
<body>
  <div style="margin-bottom: 12px; display: flex; gap: 8px;">
    <input type="file" id="file-picker" />
    <button id="btn-zoom-in">Zoom In</button>
    <button id="btn-zoom-out">Zoom Out</button>
    <button id="btn-download">Download</button>
  </div>

  <div id="viewer-container"></div>

  <script type="module">
    import { FilePreviewViewer } from './node_modules/@files-preview-app/preview-file/dist/index.js';

    const container = document.getElementById('viewer-container');
    const filePicker = document.getElementById('file-picker');

    // 1. Instantiate viewer
    const viewer = new FilePreviewViewer();

    // 2. Listen to lifecycle events
    viewer.on('loading', () => console.log('File loading started'));
    viewer.on('loaded', (info) => console.log('File loaded:', info));
    viewer.on('error', (err) => console.error('Preview error:', err));
    viewer.on('page-change', (data) => console.log('Page switched:', data));

    // 3. Render initial file
    let instance = await viewer.preview(
      container,
      'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf',
      {
        theme: 'light',
        showToolbar: true,
        toolbarPosition: 'top'
      }
    );

    // 4. Handle file selection from local disk
    filePicker.addEventListener('change', async (e) => {
      const file = e.target.files[0];
      if (file) {
        instance = await viewer.preview(container, file, { theme: 'light' });
      }
    });

    // 5. Connect custom buttons to instance methods
    document.getElementById('btn-zoom-in').addEventListener('click', () => instance?.zoomIn?.());
    document.getElementById('btn-zoom-out').addEventListener('click', () => instance?.zoomOut?.());
    document.getElementById('btn-download').addEventListener('click', () => instance?.download?.());
  </script>
</body>
</html>

šŸŽ›ļø Complete Methods Reference

1. FilePreviewViewer (Viewer Class Methods)

MethodParametersReturnsDescription
preview()container: HTMLElement, source: FileSource, options?: PreviewViewerOptionsPromise<PreviewInstance>Renders any supported file into the target DOM element. Cleans up previous renders automatically.
getInstance()NonePreviewInstance | nullReturns the active preview instance, exposing zoom, navigation, export, and rotation methods.
openInSeparateWindow()NoneWindow | nullClones current file buffer and opens it in a full-screen isolated browser tab.
setShowFileName(show)show: booleanvoidDynamically toggles the file name and format badge title bar above the toolbar.
setFileName(name)name: stringvoidDynamically updates the displayed file title in the preview panel.
setToolbarConfig(config)config: ToolbarConfigvoidDynamically reconfigures which toolbar buttons/actions are shown.
getToolbarConfig()NoneToolbarConfigReturns the active toolbar configuration.
hideToolbarAction(id)actionId: stringvoidHides a specific toolbar action by ID or alias (e.g. 'zoomIn', 'print', 'download').
showToolbarAction(id)actionId: stringvoidShows a previously hidden toolbar action.
enableToolbarAction(id)actionId: stringvoidEnables a disabled toolbar action button.
disableToolbarAction(id)actionId: stringvoidDisables a toolbar action button.
toggleThumbnails()NonevoidToggles the page/sheet thumbnail sidebar panel.
toggleFullscreen()NonevoidToggles browser fullscreen on the viewer container.
fitToPage()NonevoidScales document page or table so it fits the frame width with minimal margins.
zoomIn()NonevoidProgrammatically zooms in.
zoomOut()NonevoidProgrammatically zooms out.
setZoom(level)level: numbervoidProgrammatically sets exact zoom scale (e.g. 1.5 = 150%).
getZoom()NonenumberReturns current zoom level.
rotateCW()NonevoidRotates document or image 90° clockwise.
rotateCCW()NonevoidRotates document or image 90° counter-clockwise.
goToPage(page)page: numbervoidNavigates to a specific page or sheet (1-based index).
nextPage()NonevoidNavigates to next page or sheet.
prevPage()NonevoidNavigates to previous page or sheet.
getPageCount()NonenumberReturns total page/sheet count.
getCurrentPage()NonenumberReturns current active page number (1-based).
download()NonevoidDownloads current file with original name and detected MIME type.
print()NonevoidTriggers browser print dialog for document.
on(event, handler)event: string, handler: (data: any) => voidUnsubscribe: () => voidSubscribes to lifecycle events. Returns an unsubscribe cleanup function.
registerPlugin(plugin)plugin: PreviewPluginthisRegisters a custom renderer plugin.
registerPlugins(list)plugins: PreviewPlugin[]thisRegisters multiple renderer plugins at once.
destroy()NonevoidDestroys the active instance, removes toolbar DOM, cancels network abort controllers, and clears listeners.

2. PreviewInstance (Active Document Instance Methods)

Retrieved via viewer.getInstance() or previewRef.current.getInstance().

CategoryMethodReturn TypeDescriptionExample Usage
ZoomzoomIn()voidIncrements zoom level by 20%instance.zoomIn()
ZoomzoomOut()voidDecrements zoom level by 20%instance.zoomOut()
ZoomsetZoom(level)voidSets absolute zoom scale (e.g. 1.5 = 150%)instance.setZoom(1.5)
ZoomgetZoom()numberGets current zoom scale numberconst z = instance.getZoom()
ZoomfitToPage()voidResets zoom to fit container viewportinstance.fitToPage()
PaginationgoToPage(page)voidJumps to specific page, sheet, or slide (1-indexed)instance.goToPage(3)
PaginationgetPageCount()numberReturns total page, sheet, or slide countconst total = instance.getPageCount()
PaginationgetCurrentPage()numberReturns current 1-indexed page or sheetconst cur = instance.getCurrentPage()
RotationrotateCW()voidRotates document, image, or video 90° clockwiseinstance.rotateCW()
RotationrotateCCW()voidRotates 90° counter-clockwiseinstance.rotateCCW()
RotationgetRotation()numberReturns rotation angle in degrees (0, 90, 180, 270)const deg = instance.getRotation()
Mediaplay()voidStarts video or audio playbackinstance.play()
Mediapause()voidPauses video or audio playbackinstance.pause()
MediaisPlaying()booleanChecks if media is currently playingif (instance.isPlaying()) ...
ThumbnailsgetThumbnails()Thumbnail[]Returns list of thumbnails for sidebarconst thumbs = instance.getThumbnails()
ThumbnailstoggleThumbnails()voidToggles the page thumbnails sidebar panelinstance.toggleThumbnails()
Exportdownload()voidDownloads original file with proper name & MIMEinstance.download()
Exportprint()voidOpens browser print dialog formatted for clean outputinstance.print()
Lifecycledestroy()voidReleases memory, cancels rendering, revokes blob URLsinstance.destroy()

šŸ› ļø Toolbar Configuration & Feature Toggles

All toolbar features and buttons are completely configurable through options and instance methods. If an action is set to false, its button will not appear in the toolbar.

Via Initialization Options:

// Flat options:
await viewer.preview(container, file, {
  zoomIn: false,     // Hide zoom in button
  print: false,      // Hide print button
  openWindow: false, // Hide "Open in Separate Full Window" button
  download: true     // Keep download enabled
});

// Or nested toolbar object:
await viewer.preview(container, file, {
  toolbar: {
    zoomIn: false,
    print: false,
    copy: false
  }
});

Via Runtime Instance Methods:

// Hide an action dynamically
viewer.hideToolbarAction('zoomIn');
viewer.hideToolbarAction('print');

// Show a hidden action
viewer.showToolbarAction('zoomIn');

// Disable/enable an action button without removing it
viewer.disableToolbarAction('fitPage');
viewer.enableToolbarAction('fitPage');

// Reconfigure the entire toolbar at runtime
viewer.setToolbarConfig({
  zoomIn: false,
  zoomOut: false,
  download: true
});

Available Toolbar Toggle Keys:

Option KeyCorresponding ActionDescription
zoomInZoom InZoom in button
zoomOutZoom OutZoom out button
fitPage / fitToPageFit to PageScales document to fill frame width with minimal side margins
rotate / rotateCWRotate90° Clockwise rotation
fullscreenFullscreenFullscreen frame toggle
thumbnailsThumbnailsSidebar thumbnail toggle
downloadDownloadFile download button
printPrintBrowser clean print button
openWindow / openSeparateWindowOpen in Separate WindowOpens preview in a standalone window
copyCopy TextCopy document text to clipboard
pageNav / paginationPaginationPrevious, next, and jump-to-page input

šŸ“” Complete Events Reference

All events can be listened to via framework bindings (onLoaded, (loaded), @loaded) or viewer.on('event', handler):

Event NameFramework Prop / EventPayload TypeDescription
'loading'onLoading / (loading) / @loading{ source: FileSource }Emitted immediately when file parsing and decoding starts.
'loaded'onLoaded / (loaded) / @loaded{ metadata: FileMetadata, plugin: string }Emitted when file rendering completes successfully. Contains detected metadata.
'error'onError / (error) / @errorErrorEmitted if file download, decoding, or rendering fails.
'page-change'onPageChange / (pageChange) / @page-change{ page: number, totalPages?: number }Emitted when user navigates to another page, Excel sheet, or PPT slide.
'zoom-change'onZoomChange / (zoomChange) / @zoom-change{ zoom: number }Emitted whenever zoom level changes.
'rotate'onRotate / (rotate) / @rotate{ rotation: number }Emitted when orientation rotates (0°, 90°, 180°, 270°).
'destroy'onDestroy / (destroy) / @destroynullEmitted when viewer is cleaned up.

Practical Event Examples

1. Show File Metadata Badge on Loaded

viewer.on('loaded', ({ metadata, plugin }) => {
  console.log('File Name:', metadata.name);
  console.log('File Size:', (metadata.size / 1024).toFixed(1) + ' KB');
  console.log('Detected MIME:', metadata.mimeType);
  console.log('Renderer Plugin:', plugin);
});

2. Display Custom Error Toast Notification

viewer.on('error', (err) => {
  showToastNotification(`Cannot open file: ${err.message}`, { type: 'error' });
});

3. Synchronize External Page Counter

viewer.on('page-change', ({ page, totalPages }) => {
  pageIndicatorEl.innerText = `Page ${page} of ${totalPages || '?'}`;
});

āš™ļø Complete Properties & Options Reference

1. src Property (Accepts 5 Source Formats)

The src prop accepts any of the following types:

FormatTypeExample
Local FileFileFrom <input type="file"> event: e.target.files[0]
URL StringstringRemote or local URL: 'https://example.com/file.pdf'
BlobBlobnew Blob([binaryData], { type: 'application/pdf' })
ArrayBufferArrayBufferDirect binary buffer: await response.arrayBuffer()
TypedArrayUint8ArrayByte array: new Uint8Array(buffer)
Base64 URIstringData URI: 'data:image/png;base64,iVBORw0...'

2. options Object Reference

Passed to options prop in React/Angular/Vue or third argument to viewer.preview(container, src, options):

Option PropertyTypeDefaultDescription
theme'light' | 'dark' | 'auto''light'UI theme. 'auto' adapts to system dark mode preferences.
showToolbarbooleantrueSet false to hide built-in toolbar (e.g. when using your own custom buttons).
toolbarboolean | ToolbarConfigtrueFine-grained button visibility flags (zoomIn, print, download, pageNav, etc.).
toolbarPosition'top' | 'bottom''top'Positions toolbar at the top or bottom of the viewer container.
showFileNamebooleantrueWhen true, displays file name and format badge in title bar above toolbar.
fileNamestringundefinedCustom file title override displayed in title bar.
fitMode'width' | 'page''width'Preferred fit calculation strategy ('width' fits container width preserving aspect ratio).
showThumbnailsbooleanfalseOpens page thumbnails sidebar panel automatically on load.
classNamestring''Custom CSS class attached to the root viewer container element.
zoomnumber1.0Initial zoom multiplier (1.0 = 100%, 1.5 = 150%).
pagenumber1Initial page, slide, or sheet number to display on load (1-based).
localestring'en'UI label language localization.
metadataFileMetadataundefinedManual override object for file attributes (name, extension, mimeType, size).
standaloneViewerUrlstringundefinedCustom URL opened when user clicks "Open in Separate Full Window".
onOpenSeparateWindowfunctionundefinedCustom callback hook to handle opening preview in separate window.
pluginOptionsRecord<string, unknown>{}Custom options passed directly to underlying format renderer plugins.

šŸ“– For exhaustive details and TypeScript interfaces, see the full API Reference Documentation.

šŸŽØ CSS Variables (Theming & Custom Styling)

Customize colors, borders, and typography using standard CSS custom properties:

/* Custom Brand Theme */
.fp-viewer {
  --fp-bg: #ffffff;             /* Viewer background */
  --fp-toolbar-bg: #f8fafc;     /* Toolbar background */
  --fp-border: #e2e8f0;         /* Borders and dividers */
  --fp-text: #0f172a;           /* Text color */
  --fp-primary: #3b82f6;        /* Active buttons and highlights */
  --fp-btn-hover: #f1f5f9;      /* Toolbar button hover color */
  --fp-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}

/* Dark Theme Overrides */
.fp-theme-dark {
  --fp-bg: #0f172a;
  --fp-toolbar-bg: #1e293b;
  --fp-border: #334155;
  --fp-text: #f8fafc;
  --fp-primary: #60a5fa;
  --fp-btn-hover: #334155;
}

šŸ“‚ Supported Formats Matrix (All 10 Categories)

Every file format is rendered 100% in the browser using permissive open-source engines:

CategoryFile ExtensionsEngineLicenseSupported Features
PDF.pdfPDF.js (pdfjs-dist)Apache-2.0Multi-page canvas rendering, Zoom In/Out, Fit to page, Rotate CW/CCW, Page jump, Thumbnails sidebar, Print, Download
Word Document.docxdocx-previewApache-2.0Preserves styles, tables, bullets, images, fonts, Zoom In/Out, Fit to page, Print, Download
Excel Spreadsheet.xlsx, .xlsexceljsMITMulti-sheet tab bar, styled grid cells, borders, formatting, Zoom, Print, Download
PowerPoint.pptx, .ppsxpptx-browserMITSlide-by-slide canvas rendering, slide thumbnails sidebar, navigation jump, Zoom, Fit to slide, Print, Download
CSV / TSV Data.csv, .tsvpapaparseMITAuto-detects comma/tab delimiter, tabular grid with header styling, Zoom, Print, Download
ZIP Archives.zipfflateMITHierarchical file tree/table explorer, compression stats, instant search filter, single-file extract/download, download ZIP
Rich Markdown.md, .markdownmarked + dompurifyMIT / Apache-2.0GitHub Flavored Markdown (tables, checklists, blockquotes), syntax-highlighted code blocks, XSS sanitized, font zoom, Print, Download
3D Models.stl, .objthree (Three.js)MIT360° mouse orbit controls, perspective camera, ambient & directional lighting, wireframe vs solid toggle, reset view, Download
Images & Vector.png, .jpg, .jpeg, .gif, .webp, .bmp, .svg, .ico, .tiffNative + @panzoom/panzoom + dompurifyMIT / Apache-2.0Smooth pan & zoom, rotate 90°, SVG DOM sanitization, Print, Download
Video & Audio.mp4, .webm, .ogg, .mov, .mp3, .wav, .flac, .aacNative HTML5 MediaMITPlay/Pause, seek bar, volume control, video rotate, fullscreen, Download
Code & Text.js, .ts, .jsx, .tsx, .html, .css, .json, .xml, .yaml, .py, .java, .cpp, .sql, .sh, etc. (190+ languages)highlight.jsBSD-3-ClauseSyntax highlighting, line numbers gutter, font zoom in/out, Print, Download

šŸ›”ļø Security & Privacy Guarantee

  • šŸ”’ 100% Client-Side: Files never leave the user's browser. No documents are uploaded to third-party clouds or external rendering servers.
  • šŸ›”ļø XSS Protection: All HTML, Markdown, and SVG inputs are strictly sanitized with DOMPurify.
  • šŸ†“ 100% Permissive Open-Source: All libraries used are audited under MIT, Apache-2.0, or BSD-3-Clause. No GPL, AGPL, copyleft claims, or paid commercial subscriptions. See THIRD_PARTY_LICENSES.md.

šŸ‘Øā€šŸ’» Author & Community

Sumit Patel

šŸ“„ License

MIT Ā© 2026 Sumit Patel

Keywords

file-preview

FAQs

Package last updated on 23 Sep 2026

Related posts