Skip to content

Quickstart

Get Running Fast

If your first goal is to see the viewer running, this page starts with the shortest runnable path. Pick the native component package first, then add the preset or renderer that matches your file types; after that, tune on-demand assembly, offline assets, and toolbar behavior.

Four-step Integration

StepDecisionFast answer
1Pick the component packageUse standard packages such as @file-viewer/web, @file-viewer/vue3, or @file-viewer/react for the lightest entry; use full packages such as @file-viewer/web-full, @file-viewer/vue3-full, or @file-viewer/react-full for one-step complete capability.
2Pick the capability layerStandard packages receive preset-lite, preset-office, preset-engineering, or preset-all through options; full packages enable the complete matrix by default.
3Pass the source and optionsUse url="/files/demo.pdf" or a real File; standard packages pass a preset through options, while full packages can start with theme, toolbar, watermark, and business options only.
4Confirm style isolationPrefer the Web Component / full default Shadow DOM when host CSS is uncontrolled; framework packages can pass options.styleIsolation:'shadow'.

This page keeps the shortest runnable paths. See Component Options for the full API, renderer package matrix, toolbar, watermark, print, search, lifecycle, and guard options. See Style Isolation And Customization for Shadow DOM, tokens, and parts. See Modular Assembly for on-demand renderers and the Vite plugin.

Mobile note: for H5 and mobile browsers, give the viewer host a stable height such as height:100dvh; min-height:0, and prefer toolbar.position:'bottom-right'. React Native should load a WebView-based H5 viewer route; the DOM component cannot mount directly into native RN views. See the React mobile example.

Pick The Capability Layer First

Installing a standard component package such as @file-viewer/vue3, @file-viewer/react, or @file-viewer/web is the lightest path. It gives you the native framework component, types, controller APIs, and the core foundation; it does not install every heavy PDF, Office, CAD, Typst, archive, or engineering renderer by default.

If you want to validate the complete official demo capability first, use a full package. Full packages import @file-viewer/preset-all for you, keep the same component API, and enable the full format matrix by default. For CDN / script-tag pages, prefer @file-viewer/web-full: jsDelivr / unpkg distribute the complete IIFE directly from npm, so the host application does not need to carry the full dependency set; the script also resolves bundled workers, WASM files, fonts, and vendor assets relative to its own URL. For intranet, strict-CSP, or fully offline deployments, mirror those assets to your own static domain.

ModeInstallNotes
Light standard packagenpm i @file-viewer/vue3 @file-viewer/preset-officePick exactly the preset / renderer your product needs
Complete full packagenpm i @file-viewer/vue3-fullEnables preset-all by default for all-format workbenches
CDN fullhttps://cdn.jsdelivr.net/npm/@file-viewer/web-full@latest/dist/flyfish-file-viewer-web-full.iife.jsNo local install, ideal for script-tag validation

Add a preset or a single renderer package for the file formats your product actually needs:

PackageCoverageBest fit
@file-viewer/preset-liteText, Markdown, code, image, audio, videoLightweight attachment preview
@file-viewer/preset-officePDF, Word, Excel, PowerPoint, OFD, RTF, OpenDocumentOA, approvals, knowledge bases, contracts
@file-viewer/preset-engineeringCAD, 3D, drawing, XMind, Geo, Typst, Archive, Data, EDAEngineering, R&D, design assets
@file-viewer/preset-allFull official demo matrixDemos and internal all-format workbenches
Single rendererFor example @file-viewer/renderer-pdf or @file-viewer/renderer-wordMinimal custom format cuts

The most stable integration path is to import a preset or renderer explicitly and pass it through options.preset / options.renderers. This works in Webpack, Rspack, Rollup, Umi, classic multi-page apps, micro-frontends, and internal component libraries. Vite projects can add @file-viewer/vite-plugin later to remove manual imports and copy offline assets automatically.

Universal Setup: Inject options.preset

Install the component package and one preset:

bash
pnpm add @file-viewer/vue3 @file-viewer/preset-office
ts
import officePreset from '@file-viewer/preset-office'

export const viewerOptions = {
  preset: officePreset,
  rendererMode: 'replace',
  theme: 'light',
  toolbar: { position: 'bottom-right' }
}

Pass the same options object to your framework component:

vue
<file-viewer url="/files/demo.docx" :options="viewerOptions" />

Multiple capability bundles use the same preset field as an array, so applications do not need a second option name:

ts
import officePreset from '@file-viewer/preset-office'
import engineeringPreset from '@file-viewer/preset-engineering'

export const viewerOptions = {
  preset: [officePreset, engineeringPreset],
  rendererMode: 'replace'
}

For the smallest exact cut, skip presets and install a single renderer:

bash
pnpm add @file-viewer/vue3 @file-viewer/renderer-pdf
ts
import { pdfRenderer } from '@file-viewer/renderer-pdf'

export const viewerOptions = {
  renderers: [pdfRenderer],
  rendererMode: 'replace'
}

If a file extension is supported but the required renderer is not assembled, the viewer shows an install-oriented hint instead of a vague unsupported state.

One-Step Setup: Full Packages

Full packages are for teams that want the complete format experience first and can optimize package size later. They expose the same props, events, controller APIs, and options as standard packages, but preset-all is enabled by default:

EcosystemFull packageStandard package
Vanilla JS / Web Component@file-viewer/web-full@file-viewer/web
Vue 3@file-viewer/vue3-full@file-viewer/vue3
Vue 2.7@file-viewer/vue2.7-full@file-viewer/vue2.7
Vue 2.6@file-viewer/vue2.6-full@file-viewer/vue2.6
React 18 / 19@file-viewer/react-full@file-viewer/react
React 16.8 / 17@file-viewer/react-legacy-full@file-viewer/react-legacy
jQuery@file-viewer/jquery-full@file-viewer/jquery
Svelte@file-viewer/svelte-full@file-viewer/svelte
bash
npm install @file-viewer/vue3-full
ts
import FileViewer from '@file-viewer/vue3-full'
vue
<file-viewer url="/files/contract.pdf" :options="{ theme: 'light', toolbar: { position: 'bottom-right' } }" />

React, Vue 2, Svelte, and jQuery keep the same component shape; only the package name changes.

The Vue 3 / Vue 2.7 / Vue 2.6 full packages default their runtime asset base to /file-viewer/ and pre-fill Archive, PDF, DOCX, Excel, PPTX, CAD, Typst, Draw.io, and SQLite asset URLs. After publishing the vendor/, wasm/, and related directories copied by file-viewer-copy-assets under /file-viewer/, @file-viewer/vue3-full, @file-viewer/vue2.7-full, and @file-viewer/vue2.6-full do not need hand-written archive.workerUrl / archive.wasmUrl values.

If your static prefix is different, set the default base once during application startup:

ts
import { setDefaultFullAssetBaseUrl } from '@file-viewer/vue3-full'

setDefaultFullAssetBaseUrl('/static/file-viewer/')

Explicit options such as options.archive.workerUrl or options.pdf.workerUrl still win, which keeps tenant-specific or staged static paths easy to override.

CDN Full: Complete Script-Tag Trial

No-build pages can load the full CDN bundle directly. It avoids local package installation and is useful for demos, POCs, and classic admin pages:

html
<div id="viewer" style="height:720px"></div>

<script src="https://cdn.jsdelivr.net/npm/@file-viewer/web-full@latest/dist/flyfish-file-viewer-web-full.iife.js"></script>
<script>
  FlyfishFileViewerWebFull.mountViewer(document.getElementById('viewer'), {
    url: '/files/demo.pdf',
    options: {
      theme: 'light',
      toolbar: { position: 'bottom-right' }
    }
  })
</script>

The Custom Element route is available as well:

html
<script src="https://cdn.jsdelivr.net/npm/@file-viewer/web-full@latest/dist/flyfish-file-viewer-web-full.iife.js"></script>
<flyfish-file-viewer
  src="/files/demo.docx"
  theme="light"
  toolbar-position="bottom-right"
  style="display:block;height:720px"
></flyfish-file-viewer>

Vite Plugin: Zero-Config Assembly

In Vite projects, install and register the plugin in addition to a preset. Once fileViewerRenderers({ copyAssets:true }) is in vite.config.ts, it auto-discovers installed @file-viewer/preset-* packages, injects the renderer virtual module, and copies Worker / WASM / font / vendor assets. Application code no longer needs to import the preset manually:

bash
pnpm add @file-viewer/vue3 @file-viewer/preset-office
pnpm add -D @file-viewer/vite-plugin
ts
// vite.config.ts
import { fileViewerRenderers } from '@file-viewer/vite-plugin'

export default {
  plugins: [
    fileViewerRenderers({
      copyAssets: true
      // No preset:'office' needed; the plugin discovers installed @file-viewer/preset-office.
    })
  ]
}

Heavy users can switch to the complete preset while keeping the same Vite config:

bash
pnpm add @file-viewer/vue3 @file-viewer/preset-all
pnpm add -D @file-viewer/vite-plugin

Use explicit options only when you need customization:

OptionBest fit
copyAssets:trueCopies Worker, WASM, PDF font, CAD, Typst, Archive, Data, and other offline assets; recommended for production and intranet deployments
formats / renderersGenerates exact renderer imports when you do not use a preset, or when a preset needs a few extra formats
scan:trueScans source hints such as fileViewerFormats, data-file-viewer-formats, and upload accept attributes
preset:'auto' / autoPresets:trueKeeps installed preset auto-discovery active while scan:true is enabled
inject:falseDisables auto injection so you can import virtual:file-viewer-renderers and pass options.renderers manually
chunkStrategy:'renderer'Splits chunks by renderer for caching, debugging, and heavy-pipeline size analysis

The recommended default is fileViewerRenderers({ copyAssets:true }). Configure the advanced options only for strict bundle cuts, source-hint scanning, or complete registry control.

Vanilla JavaScript / Web Component

bash
npm install @file-viewer/web @file-viewer/preset-office
html
<flyfish-file-viewer
  id="viewer"
  src="/files/demo.pdf"
  filename="demo.pdf"
  locale="en-US"
  theme="light"
  toolbar-position="bottom-right"
  style="display:block;height:720px"
></flyfish-file-viewer>
ts
import { defineFileViewerElement } from '@file-viewer/web'
import officePreset from '@file-viewer/preset-office'

defineFileViewerElement()

const viewer = document.getElementById('viewer')
viewer.options = {
  preset: officePreset,
  rendererMode: 'replace',
  theme: 'light',
  toolbar: { position: 'bottom-right' }
}

Vue 3

bash
npm install @file-viewer/vue3 @file-viewer/preset-office
ts
import { createApp } from 'vue'
import App from './App.vue'
import FileViewer from '@file-viewer/vue3'

createApp(App).use(FileViewer).mount('#app')
vue
<script setup lang="ts">
import officePreset from '@file-viewer/preset-office'

const viewerOptions = {
  preset: officePreset,
  rendererMode: 'replace',
  theme: 'light',
  toolbar: { position: 'bottom-right' }
}
</script>

<template>
  <div style="height: 100vh">
    <file-viewer url="/files/report.docx" :options="viewerOptions" />
  </div>
</template>

React

bash
npm install @file-viewer/react @file-viewer/preset-office
tsx
import FileViewer from '@file-viewer/react'
import officePreset from '@file-viewer/preset-office'

export function Preview() {
  return (
    <div style={{ height: '100vh' }}>
      <FileViewer
        url="/files/report.pdf"
        options={{
          preset: officePreset,
          rendererMode: 'replace',
          theme: 'light',
          toolbar: { position: 'bottom-right' },
          archive: { cache: true }
        }}
      />
    </div>
  )
}

React 16.8/17 projects can use @file-viewer/react-legacy.

Locale And Copy

The viewer defaults to locale: 'auto', which follows the browser language and resolves to Chinese or English. Use the same options object across Vanilla JS / Pure Web, Vue, React, jQuery, and Svelte when you need a fixed locale or custom copy:

ts
const options = {
  locale: 'en-US',
  messages: {
    'toolbar.download': 'Save file'
  }
}

You can also group locale and copy under i18n:

ts
const options = {
  i18n: {
    locale: 'zh-CN',
    messages(key, params, locale) {
      return key === 'state.empty.title' ? '请选择文件' : undefined
    }
  }
}

Web Component users can set locale="en-US" directly on <flyfish-file-viewer>.

You can read the complete FileViewerMessageKey mapping from core. The exported object is the same copy source used at runtime, so it is the safest way to generate translation sheets, coverage checks, or custom-copy tests for the installed version:

ts
import {
  FILE_VIEWER_BUILTIN_MESSAGES,
  type FileViewerMessageKey
} from '@file-viewer/core'

const rows: Array<{
  key: FileViewerMessageKey
  zhCN: string
  enUS: string
}> = Object.keys(FILE_VIEWER_BUILTIN_MESSAGES['zh-CN']).map(key => ({
  key: key as FileViewerMessageKey,
  zhCN: FILE_VIEWER_BUILTIN_MESSAGES['zh-CN'][key as FileViewerMessageKey],
  enUS: FILE_VIEWER_BUILTIN_MESSAGES['en-US'][key as FileViewerMessageKey]
}))

messages only needs the keys you want to override. Missing keys continue to use the built-in copy for the active locale. Loading states, error states, toolbar controls, PDF / Office / OFD / archive surfaces, and standard renderer notices all follow the same options.locale / options.i18n path.

Authenticated Files

If your app must authenticate before downloading a file, fetch the file in the host app and pass a named File to the viewer:

ts
const blob = await fetch('/api/files/contract', {
  credentials: 'include'
}).then(response => response.blob())

const file = new File([blob], 'contract.pdf', { type: blob.type })

Passing a filename with an extension is important because the viewer uses it to pick the renderer.

Self-host Worker And WASM Assets

Most web apps can install the package and run. For intranet, strict CSP, offline, or custom static-prefix deployments, copy viewer assets into your app:

bash
npx file-viewer-copy-assets ./public/file-viewer

The copy command verifies PDF, archive, DOCX, spreadsheet, Draw.io, CAD, Typst, SQLite, Worker, WASM, and vendor assets. Runtime options let you point each renderer to your own static paths.

Zero-Dependency Integration: Official Demo iframe

If a customer system only needs preview capability and should not install npm packages or change its build pipeline, use the official demo build output directly. Download file-viewer-v2-*-official-demo-iframe.tar.gz from GitHub Releases, extract it to one static directory such as /file-viewer/, and keep assets/, vendor/, wasm/, and example/ together.

The simplest URL-based preview:

html
<iframe
  src="/file-viewer/iframe.html?url=/files/demo.docx"
  style="width:100%;height:720px;border:0"
  allow="fullscreen"
></iframe>

If the parent page must fetch an authenticated file first, pass the resulting Blob to the demo:

html
<input id="file" type="file">
<iframe id="viewer" style="width:100%;height:720px;border:0"></iframe>

<script>
  const viewer = document.querySelector('#viewer')

  function openFile(file) {
    const src = new URL('/file-viewer/iframe.html', location.origin)
    src.searchParams.set('from', location.origin)
    src.searchParams.set('name', file.name)
    viewer.src = src
    viewer.addEventListener('load', () => {
      viewer.contentWindow.postMessage(file, src.origin)
    }, { once: true })
  }

  document.querySelector('#file').addEventListener('change', event => {
    const file = event.target.files && event.target.files[0]
    if (file) openFile(file)
  })
</script>

from must equal the parent page origin. The demo accepts only a Blob from that origin. Prefer /iframe.html for the chrome-free entry, or /iframe on static hosts that support clean URLs. The original /index.html demo entry keeps the same url, from, name, and postMessage(Blob) protocol for existing customer integrations.

Try The Demo Locally

bash
pnpm install
pnpm dev

The main demo opens at the Vite dev server URL. The zero-dependency iframe entry is available at /iframe.html, and the comparison demo is available at /compare.html.

Released under the Apache-2.0 License.