# File Viewer full documentation corpus
> Complete bilingual corpus. For targeted retrieval, use /llms.txt and the per-page /llms.mdx/.../content.md endpoints.
# Changelog (/changelog)
## v3.1.2 - EPUB and Patch fixes, opt-in BPMN and XML views [#v312---epub-and-patch-fixes-opt-in-bpmn-and-xml-views]
* Fixed #300: EPUB orientation follows the stable reader viewport instead of transient toolbar measurements, preventing repeated layout changes. Verified with the reporter's file and browser regression.
* Fixed #304: side-by-side Patch previews keep matched rows aligned and compact, with a fixture that preserves valid patch syntax.
* Added opt-in BPMN diagrams (#297) and XML XSD validation and XSLT document views (#305). Ordinary XML stays on the text path; existing Full packages do not acquire the optional engines. The Demo includes working samples.
* Carried forward ZIP security fixes, IDML runtime assets, and dependency updates while keeping Vue 2.6/2.7 and existing Full behavior available.
This release contains 89 npm targets: 88 mainline packages at `3.1.2` and `msdoc-viewer` at `0.2.9`. DOCX remains at `0.3.32` and styled-exceljs at `0.21.6`. Issues #227, #248, and #269 still lack their reporter files and are not claimed as verified fixes.
## v3.0.3 - Word revisions, browser integration, and mobile PDF fixes [#v303---word-revisions-browser-integration-and-mobile-pdf-fixes]
* MapLibre 6.4.1 fixes the attribution HTML sanitizer bypass. Its worker stays bundled locally and survives map recreation. Update js-yaml, sharp and Vitest security versions; replace the unused Browserify toolchain with the specific build shims it supplied.
* Standard preview packages pin JSZip 3.10.2 for cross-realm binary inputs and consistent build/cold-install behavior.
* Core and renderers pin DOMPurify 3.4.15 for its XML sanitization hardening, avoiding duplicate cold-install versions without increasing size budgets.
* Demo toolbar hover no longer changes the document inset or CAD export dimensions.
* DOC preserves insertion/deletion records, paragraph marks and soft breaks. Word review modes switch without selecting the file again. Correct DOC line-spacing units and font slots restore the supplied sales contract without inventing revision marks.
* Resized spreadsheet columns now scale and survive sheet changes. Offscreen search covers real XLS input, distant columns and merged cells. CFB recovery skips only unused broken MiniFAT chains; required workbook data is still validated.
* iPhone Safari PDF navigation recovers after search and keyboard dismissal. Canceled PDF startup no longer leaves an unhandled Worker rejection.
* Vue CLI/Webpack, Angular and nested Vite integrations use the correct browser entries and local PPTX Workers. Explicit asset paths retain priority. New AMD entries support RequireJS without changing the host's `define` or relying on a CDN.
* HTML offers static preview and exact source views without running scripts or external requests. OFD resolves declared resources and namespaces and rejects invalid required pages without hanging. CAD adds permission-aware, watermarked PNG/JPEG view downloads and corrects DXF LINE and DWF/DWFx contrast.
* PDF runtime patches carry verifiable source hashes; CHM, Adobe and Illustrator security fixes are reflected in distributed Workers. Independent component source builds include their required inputs, and publication resumes by dependency layer with integrity checks.
The mainline target is `3.0.3` for 87 packages; `msdoc-viewer` advances to `0.2.6`. Upstream engines are DOCX `0.3.31`, styled-exceljs `0.21.6`, CAD `0.8.2` and DWF `0.6.7`. Vue 2.6/2.7 and existing Full capabilities remain supported; pako 3 stays deferred. This patch also includes the HTML views, AMD entry and CAD image-download features.
The private XLS from #227, the deletion-revision file behind the #236 screenshot and the historical #57 OFD remain unavailable. Constructed fixtures and the supplied contract do not establish those originals as fixed.
## v3.0.2 — Corrected patch release for spreadsheet search, DOCX shapes, and CAD monochrome output [#v302--corrected-patch-release-for-spreadsheet-search-docx-shapes-and-cad-monochrome-output]
This release supersedes 3.0.1. npm does not allow replacing packages that already have dependents, so the published 3.0.1 line cannot be completely retracted; affected 3.0.1 packages are deprecated after 3.0.2 is published.
### Issue fixes and regression coverage [#issue-fixes-and-regression-coverage]
* Fixed #247: spreadsheet search now searches parsed workbook cells outside the current virtual window, loads the target window, and jumps to the matching cell. The real `apps/viewer-demo/public/example/excel.xls` sample passes the browser regression.
* Fixed #250 by upgrading `@file-viewer/docx` to `0.3.29`, which corrects page-relative positioning for floating shapes. The reporter's `test.docx` was rendered locally with the shape content in the expected positions.
* Completed #213/#245: the CAD monochrome policy is preserved from DWF through the CAD renderer and HTML/Print output without mutating source data. The real DWF regression passes.
* Re-ran the #242 Vite/PDF CJK asset boundary, the #232 `postal-mime@3.0.0` EML parser cases, and the Vue 2.6 CLI 3 Office sample. Vue 2 remains in the release gate.
### Safe dependency updates [#safe-dependency-updates]
* Adopted the safe Dependabot subset: `pako@2.2.0`, `proj4@2.22.0`, `vite-plugin-dts@5.1.0`, `cnfast@0.2.0`, and `prettier@3.9.6`.
* pako 3 remains deferred because DICOM `Inflate` error/message semantics are consumed by `packages/renderers/dicom/src/inspect.ts`. Next 16.3.4 remains excluded because its `sharp-libvips` dependency fails the repository's LGPL license gate.
### Release composition [#release-composition]
The frozen release contains 88 npm targets from one commit: 87 mainline packages at `3.0.2` and the historical `msdoc-viewer` alias at `0.2.5`. External engines remain `@file-viewer/docx@0.3.29` and `styled-exceljs@0.21.4`.
## v3.0.1 — Host peer frameworks, PDF CJK fallback, and EML header correctness [#v301--host-peer-frameworks-pdf-cjk-fallback-and-eml-header-correctness]
### Readable text previews [#readable-text-previews]
* Added opt-in readable text previews (#235): logical-line wrapping works in regular and bounded virtual views, while structured files can use lazily loaded Prettier parser chunks with an explicit formatted-preview badge and original-source switch. The formatting byte limit is independent from large-text rendering, and original download bytes remain authoritative.
### CLI reliability and interaction [#cli-reliability-and-interaction]
* Replaced free-form format/capability entry in the interactive create/add wizard with checkbox-style renderer and format-family rows. Capabilities included by the selected profile are visibly preselected and retained, while optional rows support individual numbers, ranges, select-all, and clear-extra commands.
* Generated Vite 8 projects now declare and preflight Node `^20.19.0 || >=22.12.0` before `dev` or `build`, producing an actionable upgrade message on unsupported runtimes. Web Component events are created from the element's owning document realm with a compatibility fallback when global `CustomEvent` is unavailable.
### New format renderers [#new-format-renderers]
* Added `@file-viewer/renderer-chm`: offline in-browser CHM help reading with a Rust/WASM unpacker and a sandboxed reader for table of contents, articles, and images. Nothing leaves the browser.
* Added `@file-viewer/renderer-design`: offline Adobe design preview covering PSD/PSB layers, Illustrator native PGF and PDF-compatible surfaces, IDML/ICML/INX, INDD/XD, modern XFL animation, and swatch, brush, and resource files. It ships as an explicit opt-in package whose Worker, WASM, and font assets can be self-hosted.
### PDF [#pdf]
* Fixed the 3.0 packaging failure reported in #242 (Vite 8 + pnpm 11 + Node 22): `@file-viewer/vite-plugin` has treated pdf assets as required since 2.4, and 2.4 passed because `@fontsource-variable/noto-sans-sc` was then a runtime dependency of `@file-viewer/renderer-pdf`. 3.0.0 moved that font to devDependencies, so an installed app had no font source to copy and the missing required asset aborted `vite build`, which made rolling back to 2.4 look like the fix. In 3.0.1 the presets that activate the pdf renderer own the font source (`preset-office` and `preset-all` declare the font package, `preset-standard` takes it from `@file-viewer/assets-standard`), the published `@file-viewer/renderer-pdf` tarball carries no font copy, and when no font source resolves the asset is optional, so the build logs a warning instead of failing and PDF rendering keeps relying on the fonts embedded in each document. The #242 and profile gates keep that ownership and optionality from drifting back.
### Email [#email]
* Raised the EML parsing baseline to postal-mime `3.0.0` (#232): parts without a declared charset fall back to the header encoding, folded RFC 5322 headers unfold completely, repeated headers resolve first-wins, and `to`/`cc`/`bcc` keep their original order.
### Ecosystem package installation [#ecosystem-package-installation]
* `@file-viewer/vue3` no longer installs the host framework: `vue` moved to `peerDependencies: ">=3.3 <4"`, matching the Vue 2.6, Vue 2.7, React, React Legacy, Svelte, and jQuery packages, and the build-time icon library moved to devDependencies so the only runtime dependency is `@file-viewer/core`. Applications pinned to a Vue version outside the old `^3.5.35` range previously received a second Vue copy and crashed on mount with `Cannot read properties of null (reading 'refs')`.
* Added a host runtime contract gate: ecosystem components may only install File Viewer packages at runtime, must declare their host framework as a peer, and must keep the three Vue release lines disjoint. A cold-install check now compares resolved host framework paths immediately after install and fails with the duplicated copies listed instead of surfacing as a browser timeout.
* The `msdoc-viewer` compatibility alias moved to `0.2.5` so it follows the 3.0.1 `@file-viewer/doc` line: the alias ships the Word renderer version it resolves to, and a frozen alias could no longer be published twice. This release freezes 88 npm targets: 87 mainline packages on `3.0.1` and the `msdoc-viewer` alias on `0.2.5`.
### Dependency security [#dependency-security]
* The XMind parsing path no longer resolves `@xmldom/xmldom` 0.9.10, whose six advisories are reachable from `DOMParser.parseFromString` while previewing an untrusted file; a dependency override keeps the whole graph on 0.9.12, and the public boundary check verifies the override really lands (#246).
## v3.0.0 — Modular CLI, opt-in specialist formats, and security gates [#v300--modular-cli-opt-in-specialist-formats-and-security-gates]
Released August 27, 2026.
* Added `@file-viewer/cli`, `file-viewer-cli`, and `create-file-viewer` for new projects and existing `package.json` applications. It detects frameworks and build systems, selects framework versions, formats, presets, and assets, and supports npm, pnpm, Yarn, Bun, credential-free private registries, and integrity-checked offline tgz preparation.
* Made `standard` the recommended common-format profile without changing the eight published Full contracts. Existing `*-full` packages keep their `preset-all` format matrix, APIs, and same-version offline assets. Explicit CLI `full` selection adds later specialist capabilities after showing their size, runtime, and license boundaries.
* Kept DICOM and digital-signature containers out of unchanged Full dependencies. The optional DICOM renderer covers bounded local single-file, single-frame, and multi-frame preview for uncompressed, JPEG Lossless, JPEG-LS, and JPEG 2000 Lossless fixtures; it is not a diagnostic, PACS/DICOMweb, or multi-file-series viewer (#210).
* Added an optional signature and evidence-container renderer for bounded CMS/CAdES, RFC 3161/5544, ASiC-S/E, RFC 4998, JWS, and public OpenPGP material. It uses a permissively licensed rPGP Worker/WASM path, contains no LGPL source, and reports parsing, digest/signature checks, trust, and legal validity as separate concepts (#206).
* Fixed the reporter's five-slide PPTX layout sample, including DrawingML table bounds and insets, horizontal SmartArt text, complex shape geometry, and the PPTX Worker in Chromium, Firefox, and WebKit (#200).
* Restored the reporter's Excel table theme, header, and alternating-row styles, and kept resized column widths across sheet switches. Invalid merge metadata and stable Office width handling received matching regressions (#211/#203).
* Added nested email-attachment preview across React, React Full, React Legacy, and React Legacy Full, with malicious filename, buffer replacement, unmount, Worker, and Object URL cleanup coverage (#212).
* Re-ran the #178 Office 365/WPS in-cell image, floating drawing, TIFF, Worker transfer, double-click lightbox, and optional column-resizing suite.
* Hardened document-generated HTML/DOM boundaries for DOC, RTF, PPTX, Markdown, Mermaid, Drawing, PlantUML, and Typst. External links remain blocked by default; CSP and Trusted Types gates pass in Chromium, Firefox, and WebKit.
* Froze 84 npm targets: 83 mainline packages use 3.0.0, while the historical `msdoc-viewer` compatibility package uses 0.2.4. The external maintained engines are pinned to `@file-viewer/docx@0.3.28` and `styled-exceljs@0.21.4`.
* The release promotes only the exact tarballs produced by the frozen commit after builds, tests, security gates, cold installs, browser matrices, and `npm publish --dry-run`. Publishing does not rebuild or invent another stable version.
## v2.4.0 — Unified versions and frozen release candidates [#v240--unified-versions-and-frozen-release-candidates]
Released August 25, 2026.
* Unified the root, GitHub Release, and 56 regular npm packages at 2.4.0. The historical `msdoc-viewer` compatibility package uses 0.2.3.
* Updated the Spreadsheet and iWork paths to `styled-exceljs@0.21.3`, including prototype-safe worksheet maps, bounded XML/tag handling, and safe serialization of document-provided HTML, CSS, links, images, and attributes.
* Re-ran the #178 Office 365/WPS in-cell image, floating drawing, TIFF, Worker transfer, double-click lightbox, and optional column-resizing regressions. Version unification does not remove Excel column resizing.
* Stable publishing now promotes the exact tarballs that passed the full build, cold-install, and npm dry-run rehearsal. A receipt pins the source commit, package set, byte sizes, and SHA-512 hashes; the publish command never rebuilds them.
## v2.3.2 — Multipage TIFF and Vite 8 chunking [#v232--multipage-tiff-and-vite-8-chunking]
Released August 24, 2026.
* Added a TIFF-only lazy UTIF.js path for CCITT Group 4 and bounded multipage rendering, with shared zoom, rotation, fit width, page state, and double-click or keyboard lightbox access (#208).
* Limited encoded bytes, page count, dimensions, per-page pixels, and cumulative decoded pixels; progressive page conversion releases RGBA data and Object URLs without changing native PNG/JPEG/WEBP loading.
* Switched Vite 8 projects to Rolldown `codeSplitting.groups` while retaining Rollup `manualChunks` on Vite 5–7 and preserving user groups, priorities, array outputs, and disabled code splitting (#209).
* Re-ran the original #178 Office 365/WPS in-cell-image workbook through main-thread, Worker, TIFF drawing, and lightbox paths without removing Excel column resizing.
* Published `@file-viewer/renderer-image@2.3.1`, `@file-viewer/vite-plugin@2.3.3`, `@file-viewer/preset-lite@2.3.1`, and the unified 2.3.6 All/Full/copy-assets line. This release includes every v2.3.1 security correction.
## v2.3.1 — Legacy DOC rendering security [#v231--legacy-doc-rendering-security]
Released August 24, 2026.
* Encoded document-provided font names and generated attributes in the legacy DOC HTML API.
* Blocked external DOC links by default. Internal bookmarks remain available; explicit opt-in permits only HTTP(S), email, telephone, and safe relative links.
* Sanitized DOC markup again at the mount boundary with DOMPurify 3.4.13 and inserted renderer CSS through `textContent`.
* Kept the sanitizer in the DOC lazy path. Its minified gzip size is 10,923 bytes and a 15 KiB release gate prevents unbounded growth.
* Published `@file-viewer/doc@2.3.1`, `msdoc-viewer@0.2.2`, `@file-viewer/renderer-word@2.3.2`, and the 2.3.4 Office/Full/copy-assets patch line.
## v2.3.0 — Office/iWork coverage and verified file fixes [#v230--officeiwork-coverage-and-verified-file-fixes]
Released August 20, 2026.
* Added stable Pages, Numbers, Keynote, WordPerfect, Hangul, DBF, FB2, XLA/XLAM, and POT routes to the generated 221-extension, 32-pipeline matrix.
* Fully released the fixes tracked by #174, #178, #179, #195, #198, and #201-#204. #200 remains open because the original PPTX is still missing.
* Fixed Excel Office 365 and WPS in-cell images, workbook drawings, saved column widths, Shadow DOM column resizing, and double-click image preview. A reporter-provided TIFF drawing is now decoded on demand in the browser across main-thread, Worker, and lightbox paths.
* Updated the DOCX engine to `@file-viewer/docx@0.3.27` for complex frames, sections, positioned pages, and anchored content; the Worker cache key now matches the runtime.
* Hardened PPTX Worker output, rendered Markdown, archive filename decoding, package dependencies, and offline Worker/WASM delivery.
* Kept PPT-only CJK fonts and native WASM out of PPTX-only builds, and made Vite 5–8 resolve the `renderer-presentation/pptx` export subpath correctly (#205).
* The source and GitHub release are v2.3.0. Immutable npm corrections use `@file-viewer/renderer-spreadsheet@2.3.2`, `@file-viewer/renderer-iwork@2.3.1`, `@file-viewer/renderer-word@2.3.1`, `@file-viewer/renderer-presentation@2.3.1`, `@file-viewer/vite-plugin@2.3.2`, and the 2.3.3 Office/Full/copy-assets line. TIFF drawing metadata is supplied by `styled-exceljs@0.21.2`.
## v2.2.9 — PPTX and Markdown rendering security [#v229--pptx-and-markdown-rendering-security]
The npm packages were published August 13, 2026; the GitHub Release was finalized August 17, 2026.
* Sanitized PPTX Worker HTML, SVG, inline styles, URLs, event attributes, scripts, and unsafe global CSS before they enter the preview DOM.
* Sanitized Marked output with DOMPurify and hardened links opened in a new window with `noopener noreferrer`.
* Added browser gates for malicious Markdown, synthetic PPTX Worker output, and real malicious PPTX files across normal and virtualized rendering paths.
* Kept the published capability matrix at 54 npm targets, 208 extensions, and 25 preview pipelines.
## v2.2.8 — Large spreadsheets, OFD first paint, and PPT watermark polish [#v228--large-spreadsheets-ofd-first-paint-and-ppt-watermark-polish]
Released August 11, 2026.
* Bounded spreadsheet auto-width sampling so large workbooks no longer require a complete row scan during every fit operation.
* Disabled OFD transform transitions until initial layout stabilizes, removing the first-frame jump while preserving reduced-motion behavior.
* Reduced the open-source binary PPT watermark to a single bottom-right mark while preserving the engine's mandatory licensing boundary.
* Hardened release automation around npm timeouts, uncertain registry state, and interrupted uploads.
## v2.2.7 — PDF zoom anchoring and legacy Word tolerance [#v227--pdf-zoom-anchoring-and-legacy-word-tolerance]
Released August 11, 2026.
* Kept PDF zoom anchored to the current visible area instead of allowing the document to drift behind navigation.
* Improved tolerance for HTML-in-WordDocument legacy DOC files.
* Shipped the fixes consistently across npm, GitHub Releases, component repositories, the demo, documentation, website, and Docker images.
## Complete history [#complete-history]
* [Browse all GitHub Releases](https://github.com/flyfish-dev/file-viewer/releases)
* [Read the complete Chinese changelog](/zh/changelog)
* [Verify the current format matrix](/guide/formats)
---
# Support File Viewer (/donate)
File Viewer remains Apache-2.0 open source. Sponsorship helps fund compatibility work, documentation, examples, offline assets, and long-term maintenance.
* [GitHub Sponsors](https://github.com/sponsors/wybaby168): one-time or recurring sponsorship through GitHub.
* [WeChat / Alipay](https://dev.flyfish.group/sponsor?source=github): convenient one-time support for domestic users.
* [Enterprise support](https://dev.flyfish.group/shop): private deployment, custom compatibility work, and requirements with committed response expectations.
GitHub Sponsors is received by [@wybaby168](https://github.com/wybaby168), the primary maintainer of File Viewer. Sponsorship supports open-source maintenance and does not include a service-level agreement unless a published tier explicitly says otherwise.
[查看中文说明](/zh/donate)
---
# BPMN diagrams (/guide/bpmn)
Available in 3.1.2 and later. BPMN is an explicit opt-in; Full packages keep their existing dependency set.
Install `@file-viewer/renderer-drawing` and its optional peer `bpmn-js@18.28.0`, then register it with any standard component:
```ts
import { mountViewer } from '@file-viewer/web'
import { bpmnRenderer } from '@file-viewer/renderer-drawing/bpmn'
mountViewer(document.querySelector('#viewer'), {
url: '/documents/process.bpmn',
filename: 'process.bpmn',
options: { renderers: [bpmnRenderer] }
})
```
The read-only view renders BPMN 2.0 XML with BPMN DI layout. Use its toolbar to switch between the diagram and original source, pan, zoom, fit the diagram, or select another diagram in the same file. Source mode does not execute XML or embedded process scripts. Missing layout and malformed files produce a visible diagnostic while keeping the source available.
`createBpmnRenderer({ initialView: 'source', maxFileBytes: 5 * 1024 * 1024 })` starts with source view and a smaller input limit. The default limit is 20 MiB. This is not a modeler or workflow execution engine; it does not invent missing diagram coordinates.
The upstream bpmn.io license requires its watermark to stay visible. The optional dependency's license is not replaced by File Viewer's Apache-2.0 license. See the renderer's `THIRD_PARTY_NOTICES.md` for the exact terms.
If your application overlays a floating toolbar at the bottom, set `--file-viewer-content-end-inset` on the viewer host to the occupied height. The diagram reserves that space without modifying the upstream watermark. The Demo checks that its controls do not cover the logo or link.
The Demo's **BPMN diagram and source** sample is independently constructed and redistributable. Issue attachments are tested locally, not automatically republished as demo files.
---
# File Viewer CLI (/guide/cli)
Use `npx file-viewer-cli@latest ...` for a zero-install command: this single-bin carrier delegates to the exact same-version `@file-viewer/cli`. After adding the scoped package to a project, use its local `file-viewer` executable directly.
Create Choose a framework, a validated runtime version, a format profile, extra formats, package manager, and asset location.
Add Inspect an existing package.json project, show the complete plan, install exact packages, and wire the generated integration entry.
Assets Deploy only selected capability assets or preserve the complete historical copy-assets command and Full-package contract.
Prepare Build an integrity-checked local tgz directory from an explicit npm or private registry with bounded concurrency.
## Start here [#start-here]
Run the interactive project creator:
```bash
npm create file-viewer@latest my-viewer
# or
pnpm create file-viewer my-viewer
```
The wizard shows the framework, profile, File Viewer release, validated framework versions, and optional formats before it asks for final confirmation. Cancelling or answering no leaves the project unchanged.
For a reproducible non-interactive run, pass every decision explicitly:
```bash
npx file-viewer-cli@latest create my-viewer \
--framework vue3 \
--profile standard \
--formats pdf,docx,xlsx,pptx \
--package-manager pnpm \
--non-interactive \
--yes
```
`--yes` is the write and installation confirmation for `create`, `add`, and `install`. Without it, non-interactive runs print the plan and do not install packages or write files.
## Choose a framework and version [#choose-a-framework-and-version]
| CLI value | Generated integration | Version choice |
| -------------- | ------------------------------------------------------ | -------------------------------------------------- |
| `web` | Vanilla JavaScript plus the File Viewer Custom Element | Browser template |
| `vue3` | Native Vue 3 component | Validated Vue 3 version from the installed catalog |
| `vue2.7` | Native Vue 2.7 component | Validated Vue 2.7 version |
| `vue2.6` | Native Vue 2.6 component | Validated Vue 2.6 version |
| `react` | React 18 or 19 component | Choose a validated React 18/19 version |
| `react-legacy` | React 16.8/17-compatible component | Validated legacy React version |
| `svelte` | Native Svelte action/component setup | Choose a validated Svelte 3, 4, or 5 version |
| `jquery` | jQuery plugin integration | Validated jQuery version |
The interactive wizard lists exact versions frozen in the installed CLI catalog. In CI, use `--framework-version `. The generated Vite and framework-plugin versions are selected as one tested template; the CLI does not combine arbitrary runtime versions.
## Choose a profile [#choose-a-profile]
| Profile | What it means | Recommended use |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| `standard` | Common Word, PDF/OFD, modern PPTX, Spreadsheet, Archive, Email, Text, Image, and Media capabilities with a selective asset pack | Recommended default for new applications |
| `lite` | Text, Markdown/code, image, audio, and video | Small attachment previews |
| `office` | The established Office preset, including its compatibility formats | Existing Office-focused integrations that need that exact preset contract |
| `engineering` | The established engineering preset | CAD, 3D, EDA, Geo, and engineering attachments |
| `all` | The published `preset-all` compatibility matrix | Existing modular integrations that explicitly use `preset-all` |
| `full` | The matching historical `@file-viewer/*-full` package plus every later opt-in capability in the CLI catalog | Explicit all-capability setup when install size is acceptable |
| `custom` | No fixed preset; add only selected format/capability packages | Strict dependency control |
Standard and Full are different contracts. `standard` is the recommended common-format default. The eight published `@file-viewer/*-full` packages keep their existing `preset-all`, runtime-asset, API, and format behavior; they are not silently changed to `standard`. Installing a Full package directly also does not auto-add later specialist packages. Choosing `--profile full` in this CLI keeps that Full package intact and adds the catalog's later explicit opt-ins. The current additional opt-ins are DICOM and digital-signature containers, so the CLI prints their weight, runtime, and license boundaries before confirmation.
Use `file-viewer plan` before choosing Full if download size matters:
```bash
npx file-viewer-cli plan --framework react --profile full
```
The plan prints pinned packages, asset commands, heavy capabilities, license notices, and the current measured Full install range. It does not hide the Full cost behind a small top-level tarball number.
## Select formats and optional capabilities [#select-formats-and-optional-capabilities]
Pass file extensions or capability ids during create/add:
```bash
npx file-viewer-cli create viewer \
--framework react \
--profile standard \
--formats dwg,typst \
--yes
```
Inspect the catalog, then change an initialized project:
```bash
npx file-viewer-cli list
npx file-viewer-cli config add dwg --write
npx file-viewer-cli config add dicom --write
npx file-viewer-cli config add p7m --write
npx file-viewer-cli config remove dwg --write
npx file-viewer-cli plan
npx file-viewer-cli install --yes
```
Heavy capabilities stay explicit in `standard`. The generated module imports only the fixed profile and selected additions, and runtime code still loads the matching renderer only after its format is opened.
Every selected capability is registered in the same generated File Viewer configuration. DICOM, signed containers, Office files, PDF, and the rest use the same component, source input, lifecycle, and toolbar; the CLI never creates a second viewer page or a format-specific application entry.
### DICOM boundary [#dicom-boundary]
`dicom` installs the optional local DICOM Part 10 renderer. It supports one local single-frame or multi-frame file, with bounded decoding and frame navigation. It does **not** provide multi-file series assembly, PACS/DICOMweb, MPR, segmentation, diagnostic interpretation, or an embedded OHIF application.
### Digital-signature boundary [#digital-signature-boundary]
`p7m` (or the `signature` capability id) installs the optional local signature and evidence-container renderer. It inspects bounded CMS/CAdES, RFC 3161/5544 timestamps, ASiC-S/E, RFC 4998 evidence records, JWS, and public OpenPGP material in Workers. Cryptographic verification results are kept separate from certificate/key trust, qualified-signature status, policy compliance, and legal validity. Private-key operations, automatic decryption, remote `jku`/`x5u` fetching, full XAdES, and archival-policy validation are intentionally excluded.
## Create a new project [#create-a-new-project]
The creator writes a small Vite project plus the File Viewer integration only after the plan is confirmed. Depending on the selected framework, the scaffold contains:
* `package.json`, `index.html`, and `src/main.mjs`;
* Svelte-specific `src/App.svelte` and `vite.config.mjs` when required;
* `file-viewer.config.json`, the durable selection record;
* `file-viewer.generated.mjs`, the default deterministic renderer registration module;
* one import marker in a recognized application entry;
* exact File Viewer dependencies and selected static assets.
Preview a create without writing:
```bash
npx file-viewer-cli create ./viewer \
--framework svelte \
--framework-version \
--profile standard \
--non-interactive \
--json
```
Use `--force` only after reviewing the dry run. It allows replacement of conflicting CLI scaffold/config/generated files; it is not a general permission to rewrite arbitrary application files.
## Add File Viewer to an existing project [#add-file-viewer-to-an-existing-project]
Run `add` from the directory containing `package.json`, or pass that directory positionally:
```bash
cd existing-app
npx file-viewer-cli add
# same operation from another directory
npx file-viewer-cli add ./existing-app
```
The inspection covers:
* the `packageManager` field first, then lockfiles;
* Vue, React, Svelte, or jQuery dependencies and their declared runtime line;
* an installed standard/preset/Full File Viewer profile;
* Vite, Vue CLI, Webpack, Next.js, or Nuxt 2/3 build configuration;
* a statically provable Vite `publicDir` or Nuxt `dir.public` / `dir.static`, plus the conventional Vue CLI and Next.js public directory;
* existing File Viewer packages and catalog-version drift;
* supported application entries that can import the generated module.
It stops on ambiguous multiple frameworks or multiple installed profiles and asks for an explicit `--framework` or `--profile`. Dynamic or disabled public directories, multiple build configs, generic Webpack output, and unknown build systems produce concrete `manualSteps` and fail closed before installation or file writes; resolve the build target and pass a contained `--asset-target` to continue. If an existing framework version does not exactly match a validated scaffold version, the CLI preserves that runtime and prints a warning instead of silently rewriting the project.
First review the detected state and commands:
```bash
npx file-viewer-cli add . --profile standard --json
```
Then apply the same choice:
```bash
npx file-viewer-cli add . --profile standard --yes --non-interactive
npx file-viewer-cli verify --json
```
If no recognized application entry exists, `add` fails before installation or writes. Pass `--entry ` explicitly; do not inject the browser integration into an SSR-only entry.
## Configuration and generated integration [#configuration-and-generated-integration]
The default `file-viewer.config.json` is project-relative and safe to commit:
```json
{
"schemaVersion": 1,
"framework": "vue3",
"profile": "standard",
"formats": ["dwg"],
"capabilities": [],
"assetTarget": "public/file-viewer",
"generatedModule": "file-viewer.generated.mjs",
"locale": "en"
}
```
| Field | Purpose |
| -------------------------------- | ----------------------------------------------------------------------------- |
| `framework` / `frameworkVersion` | Native integration and exact validated runtime target |
| `profile` | Fixed preset, compatibility Full, or custom selection |
| `formats` / `capabilities` | Explicit additions resolved through the frozen catalog |
| `assetTarget` | Project-relative static directory; defaults to `public/file-viewer` |
| `generatedModule` | Project-relative deterministic registration module |
| `source` | Explicit registry or integrity-manifest offline directory |
| `assetBaseUrl` | Explicit self-hosted/CDN runtime base; omitted means local same-origin assets |
| `managedPackages` | Packages installed and owned by the CLI for safe heavy-dependency cleanup |
| `locale` | CLI display language; JSON field names remain stable English keys |
Generate or inspect the module separately:
```bash
npx file-viewer-cli generate
npx file-viewer-cli generate --write
```
Edit the config and regenerate rather than editing the generated file. User-owned files are not overwritten unless `--force` is explicit.
### Install recovery boundary [#install-recovery-boundary]
Before a confirmed create/add/install package-manager step, the CLI atomically moves an existing project-local `node_modules` plus Yarn unplugged directory into an adjacent same-filesystem backup. It also snapshots `package.json`, existing lockfiles, Yarn PnP/install-state files, CLI config/generated integration, and the managed asset target. A handled package-manager or asset failure restores those bytes. If the atomic staging area cannot be established, the CLI fails before invoking the package manager.
An abrupt process or host termination is outside the handled-error transaction and can leave `..file-viewer-install-*` beside the project. Inspect and restore that backup before rerunning; do not delete it blindly. Package-manager caches, including a project-local Yarn cache, are not rolled back. The CLI removes an obsolete heavy dependency only when `managedPackages` records that package as CLI-owned; an untracked declaration remains user-owned and is preserved.
## Asset commands and copy-assets compatibility [#asset-commands-and-copy-assets-compatibility]
For a configured modular project, install or repair only the selected asset owners:
```bash
npx file-viewer-cli assets --write
```
The original aggregate command remains available with the same package and bin:
```bash
npx --no-install file-viewer-copy-assets ./public/file-viewer
# Equivalent unified CLI entry
npx file-viewer-cli copy-assets ./public/file-viewer
```
`file-viewer assets` also preserves the legacy copy behavior when no project config exists and legacy target/options are supplied. With a modular config present, it follows the selected asset plan instead; legacy flags cannot be mixed into that plan.
| Legacy option/environment | Behavior |
| ------------------------------- | ------------------------------------------------------------------------------- |
| `[target-directory]` | Defaults to `public/file-viewer` |
| `--renderers ` | Copies only named renderer asset groups |
| `--no-clean` | Merge mode; this is the default and preserves unrelated files |
| `--clean --confirm` | Replace only a dedicated safe `file-viewer` target after both flags are present |
| `FILE_VIEWER_PUBLIC_DIR` | Default output directory |
| `FILE_VIEWER_SKIP_ASSET_COPY=1` | Explicit CI skip |
| `INIT_CWD` | Calling project root used by package-manager execution |
The copy operation writes a manifest and receipt, validates required files, refuses path escapes/symlink targets, and does not overwrite unowned or externally modified assets. Existing Full-package commands keep delegating to the same-version implementation. A complete deployment of `@file-viewer/web-full/dist/` already contains its payload and needs no copy step.
## Private registry [#private-registry]
Use HTTPS for a remote registry. Plain HTTP is accepted only for an explicit loopback host such as `127.0.0.1` during local testing:
```bash
npx file-viewer-cli add . \
--profile standard \
--registry https://registry.example.com/ \
--cache-dir .file-viewer/package-cache \
--yes
```
The CLI does not silently use an ambient registry to fetch a missing copy-assets payload. Registry URLs containing a username or password are rejected. Configure authentication in the package manager's user/CI settings; do not place credentials in the project config or command history.
`--registry` affects package acquisition only. Runtime Workers, WASM, fonts, and vendor assets remain self-hosted unless `--asset-base-url` is explicitly set to an approved origin.
## Prepare an offline tgz directory [#prepare-an-offline-tgz-directory]
`prepare` and its `cache` alias download the exact File Viewer-owned dependency closure from an explicit registry. Downloads use concurrency `1-8`; every tarball is checked for a regular contained file, SHA-512, package identity, version, and dependency metadata before the result is committed atomically with `file-viewer-offline-manifest.json`. Integrity proves that bytes match the prepared manifest; it does not establish registry provenance, so use a registry you trust.
Preview first:
```bash
npx file-viewer-cli prepare \
--framework vue3 \
--profile standard \
--registry https://registry.npmjs.org/ \
--offline-dir .file-viewer/offline
```
Prepare after review:
```bash
npx file-viewer-cli prepare \
--framework vue3 \
--profile standard \
--registry https://registry.npmjs.org/ \
--offline-dir .file-viewer/offline \
--concurrency 4 \
--yes
```
Use the verified directory in the target environment:
```bash
npx file-viewer-cli add . \
--profile standard \
--offline-dir .file-viewer/offline \
--cache-dir .file-viewer/package-cache \
--yes \
--non-interactive
```
The offline directory contains the File Viewer-owned package closure, including compatibility packages required by the selected capabilities and the exact `@file-viewer/cli` used by `create-file-viewer`. It deliberately does not mirror unrelated framework packages or every third-party dependency already declared by the application. A fully air-gapped install must also provide the package-manager cache for those dependencies. npm, pnpm, Yarn Classic, and Yarn Berry receive generation-correct offline enforcement; Bun still requires a pre-populated cache.
`--registry` and `--offline-dir` are mutually exclusive during installation. An existing offline directory is reused only when its requested roots, registry, filenames, versions, and integrity hashes all match.
## Help and language [#help-and-language]
The CLI follows the system language when possible and supports four explicit help languages:
```bash
file-viewer --help --lang en
file-viewer --help --lang zh-CN
file-viewer --help --lang ja-JP
file-viewer --help --lang de-DE
file-viewer create --help --lang en
file-viewer add --help --lang zh-CN
file-viewer doctor --help --lang ja-JP
```
Prompts and human-readable plan labels are localized. `--json` always uses stable English keys for CI and tooling.
### Commands [#commands]
| Command | Purpose | Write gate |
| --------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------- |
| `create [dir]` | Create a buildable project | Interactive confirmation or `--yes` |
| `add [dir]` | Detect and integrate an existing project | Interactive confirmation or `--yes` |
| `list` | List formats, renderer ids, packages, weights, licenses, and asset owners | Read-only |
| `plan` | Print the exact install and asset plan | Read-only |
| `init` | Create/update the project config | `--write` |
| `config add/remove ` | Change explicit formats/capabilities | `--write` |
| `generate` | Produce the deterministic integration module | `--write` |
| `install` | Install exact packages and assets from the config | `--yes` |
| `assets` | Install/repair configured assets, or use legacy mode without config | `--write` in configured mode |
| `copy-assets` | Run the complete legacy copy-assets contract | Direct target write; cleanup also needs `--clean --confirm` |
| `prepare` / `cache` | Build a verified local tgz directory | `--yes` |
| `doctor` | Report dependency, entry, receipt, hash, and asset problems | Read-only |
| `verify` | Run doctor and exit non-zero on errors | Read-only |
### Common options [#common-options]
| Option | Purpose |
| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
| `--project ` | Project root; positional `create/add ` is also supported |
| `--framework ` | Select one of the eight framework integrations |
| `--framework-version ` | Select an exact catalog-validated runtime template |
| `--profile ` | `standard`, `lite`, `office`, `engineering`, `all`, `full`, or `custom` |
| `--formats ` / `--capabilities ` | Add exact catalog entries |
| `--package-manager ` | `npm`, `pnpm`, `yarn`, or `bun` |
| `--package-manager-version ` | Exact package-manager version; records and distinguishes Yarn Classic from Yarn Berry |
| `--asset-target ` | Contained project-relative asset directory |
| `--output ` / `--config ` | Contained project-relative generated/config files |
| `--registry ` | Explicit npm/private registry |
| `--offline-dir ` | Integrity-manifest local tgz directory |
| `--cache-dir ` | Controlled package-manager cache/store |
| `--concurrency ` | `prepare/cache`: `1-8`; install package-manager network/script concurrency: `1-32` |
| `--file-viewer-version ` | Require an exact match with the installed CLI catalog |
| `--asset-base-url ` | Explicit approved runtime asset base; local remains the default |
| `--json` | Machine-readable output with stable English keys |
| `--non-interactive` | Disable prompts for CI |
| `--yes` / `--write` | Explicit execution gates for their command groups |
| `--force` | Replace conflicting CLI-managed config/generated/scaffold files after review |
| `--dry-run` | Force every mutating command into a zero-write, zero-install preview even when `--yes` or `--write` is present |
## CI pattern [#ci-pattern]
Keep planning and mutation separate:
```bash
# Reviewable, no writes
npx file-viewer-cli plan \
--framework vue3 \
--profile standard \
--formats dwg \
--json > file-viewer-plan.json
# Apply exact catalog choices
npx file-viewer-cli add . \
--framework vue3 \
--profile standard \
--formats dwg \
--non-interactive \
--yes
# Fail CI when versions, entry imports, receipts, hashes, or assets drift
npx file-viewer-cli verify --json
```
The JSON plan contains command and argument arrays instead of a shell-interpolated string, so automation can review and execute it without evaluating user-controlled shell text.
## Troubleshooting [#troubleshooting]
| Message or symptom | What to do |
| ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| `No package.json was found` | Run `create` for a new project, or run `add` from the package.json directory. |
| Multiple framework/profile runtimes detected | Pass the intended `--framework` / `--profile`; the CLI will not guess. |
| Requested File Viewer version differs from the catalog | Run the matching `@file-viewer/cli@` instead of mixing release catalogs. |
| Existing framework is not a validated scaffold runtime | Keep it and review the warning, or choose a validated `--framework-version` deliberately. |
| Missing copy-assets payload | Install the matching Full/copy package, configure an explicit registry, or provide the verified offline directory. |
| Worker/WASM/font request returns HTML or 404 | Run the configured asset step, serve the target at the configured base, and verify MIME types on the production origin. |
| Full install takes too long | Use `standard` or `custom`; prepare a private-registry/offline cache when Full is a real requirement. |
Related: [modular profiles](/guide/v3-modular-profiles), [on-demand renderers](/guide/on-demand-renderers), [distribution](/guide/distribution), and [format truth](/guide/formats).
---
# Comparison (/guide/compare)
File Viewer is a pure frontend file preview component for internal tools, intranet systems, and private deployments. It is designed for quick business-file preview, triage, search, print, export, and self-hosted delivery. It is not a professional editor, and it does not promise native-app fidelity for every complex file.
## Open-source component vs commercial edition [#open-source-component-vs-commercial-edition]
The open-source File Viewer and the commercial edition are not mutually exclusive. The open-source edition provides browser-native, multi-format, offline-ready preview. The commercial edition comes from the Flyfish Office product line and replaces the Office document capability with a self-developed native document engine, giving the same File Viewer integration a `file-viewer-pro` style Office experience.
| Dimension | Open-source File Viewer | Commercial / file-viewer-pro path |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Formats | 275 registered extensions (225 stable, 50 experimental) across 47 preview pipelines for PDF/OFD, Office/iWork, CAD, Typst, archives, email, ebooks, diagrams, media, 3D, data assets, Adobe design files, optional local DICOM, digital-signature containers, and byte inspection; common capabilities use presets while Adobe design, DICOM, signature, and binary-inspector formats stay explicit opt-ins | Strengthens the Word, Excel, and PowerPoint deep end. It can replace the Word / Spreadsheet / Presentation capability in `preset-office` while PDF, OFD, CAD, Archive, and other formats continue to use open-source renderers |
| Fidelity | Optimized for readable, searchable, printable previews embedded in business systems. DOCX is currently flow-first, and Excel/PPTX target common preview needs rather than native Office pixel parity | The self-developed native document engine targets pagination, fonts, tables, shapes, headers/footers, comments/revisions, and complex deck layouts for contracts, reports, archives, and formal delivery |
| Performance | A light core plus lazy renderer loading keeps most attachment centers responsive. Worker/WASM assets load on demand, while extreme large files should be validated with real samples | Large documents, large spreadsheets, and complex decks get Worker parsing, paginated or chunked rendering, virtual scrolling, caching, and memory tuning to keep the main thread smooth |
| Licensing and support | File Viewer-authored code is Apache-2.0 and usable in commercial products. The independently versioned binary-`.ppt` engine, `@file-viewer/ppt`, keeps its own license and its public runtime is included in Demo/Full/CDN assets with the visible watermark. Community issues, sponsorship, and priority support can help, but final launch validation remains with the product team | Commercial licensing, private delivery, priority support, sample regression, custom compatibility work, and watermark-free PPT delivery for teams that need clear ownership and timelines |
## Replacing the Office capability [#replacing-the-office-capability]
Commercial delivery provides a pluggable Office preset or renderer set. Your app keeps the same Vue, React, Svelte, jQuery, Web Component, or Vanilla JS component entry. Themes, watermarks, toolbar behavior, search, events, and non-Office formats stay on the same File Viewer contracts; only the Word, Excel, and PowerPoint rendering path switches to the commercial engine.
```ts
import FileViewer from '@file-viewer/vue3'
import engineeringPreset from '@file-viewer/preset-engineering'
import { commercialOfficePreset } from './vendor/file-viewer-pro-office'
const viewerOptions = {
rendererMode: 'replace',
preset: [
commercialOfficePreset,
engineeringPreset
],
theme: 'light'
}
```
The actual package name and delivery channel depend on the commercial license. The stable pattern is what matters here: `core`, component packages, and non-Office renderers remain unchanged, while the Office preset / renderer can be replaced by the commercial engine.
## File Viewer vs conversion services [#file-viewer-vs-conversion-services]
| Approach | Strengths | Limits |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| Backend conversion | Can normalize files to PDF/images for caching, archival workflows, permission auditing, and unified fallback behavior | Requires conversion workers, queues, temporary files, fonts, caches, retries, and cleanup; private deployment can be costly |
| Office Online / cloud services | High fidelity, low maintenance, mature collaboration features | Not always suitable for intranet, private deployment, sensitive files, offline environments, or strict compliance requirements |
| File Viewer | Pure frontend, self-hostable, lazy-loaded, and easy to embed in business applications | Complex Office / CAD files still need real-file regression; not a replacement for professional editors or archival conversion |
## When File Viewer fits best [#when-file-viewer-fits-best]
* Files should not be sent to a third-party conversion service.
* The app runs in an intranet, private deployment, offline environment, or strict CSP setup.
* One component needs to cover Office, PDF/OFD, CAD, archives, email, images, media, code, and structured data.
* The product goal is preview, triage, search, print, export, and download rather than editing.
* The frontend team wants renderer/preset composition instead of many unrelated viewer embeds.
## When backend conversion is better [#when-backend-conversion-is-better]
* Long-term archival requires every file to become a stable PDF or image.
* Very large files make browser memory or mobile performance the main constraint.
* The workflow needs maximum fidelity, batch conversion, OCR, burned-in watermarks, audit records, or asynchronous review queues.
* The team already runs a reliable LibreOffice, OnlyOffice, or commercial conversion service and can absorb the operational cost.
## Recommended mix [#recommended-mix]
Many production systems can combine both approaches:
* Use File Viewer for instant browser-side preview by default.
* Trigger backend PDF conversion for archival, contracts, audit, or strict consistency cases.
* Deploy File Viewer Worker, WASM, font, and vendor assets with the rest of the app's static resources. The Full/CDN payload includes binary `.ppt` under `vendor/ppt/`; use `options.presentation.pptModuleUrl` and matching asset URLs only for a non-standard route.
* Collect real compatibility feedback through issues and sanitized samples instead of trusting synthetic files only.
## Validation checklist [#validation-checklist]
* Try Word, Excel, PowerPoint, PDF, DWG, ZIP, and EML in the [demo](https://demo.file-viewer.app).
* Validate the real formats your product cares about with sanitized files.
* Check mobile WebView behavior, intranet static paths, Worker/WASM MIME types, CSP, and fonts.
* For Office / CAD fidelity, review the [format fidelity notes](./format-fidelity).
---
# Demo Guide (/guide/demo)
The current workspace starts with a real DOCX, reveals the file capsule when the top controls are engaged, then opens the sample library and switches renderer pipelines.
## Demo URLs [#demo-urls]
* Main demo: [demo.file-viewer.app](https://demo.file-viewer.app)
* iframe entry: [demo.file-viewer.app/iframe?url=/example/en/calibre-demo.docx](https://demo.file-viewer.app/iframe?url=/example/en/calibre-demo.docx)
* Document comparison: [demo.file-viewer.app/compare.html](https://demo.file-viewer.app/compare.html)
* Official portal: [file-viewer.app](https://file-viewer.app)
## What To Check [#what-to-check]
| Area | What to verify |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Source controls | Open file, Paste link, and Samples each open their own anchored panel instead of sharing one generic dialog |
| File capsule | The filename and correct format icon open the sample library; on desktop, the capsule separates on hover and flows back into the top bar one second after pointer leave |
| Recent files | URL and sample history persists in local storage, each item can be removed, and the compact history control restores the panel |
| Sample selector | Files are grouped by type, collapsible, icon-led, and the active file group stays discoverable in light and dark themes |
| Toolbar | Search, fit, theme, download, print, HTML export, watermark, zoom, navigation, and format-specific actions appear only when supported |
| Settings | More exposes the full option surface, including document-background mode, density, fit, watermark, archive, and current-format controls |
| PDF | Page thumbnails, outline tree, floating toolbar, fit-to-width, search highlights, and side panel toggling |
| Word | Stream-style document reading, correct text flow, printing without clipped first-page-only output |
| Spreadsheet | Sheet tabs remain readable on desktop and mobile; optional column resize can be enabled |
| Image | Open `multipage-ccitt-g4.tif` to verify two TIFF pages, group zoom/rotation/fit, page state, and double-click or keyboard lightbox access |
| IFC | Open either buildingSMART IFC4 fixture to verify the local Web-IFC import worker, canvas, Fit, selection, and property panel without a runtime CDN |
| Binary inspector | Open the raw, PE, ELF, Mach-O, ZIP, WASM, PNG, and Java-class samples to verify the explicit read-only structure tree and virtualized byte rows |
| Archive | Nested entries preview through the same renderer registry, with safe metadata filtering, cache support, optional compact `ui.density:'compact'` spacing via `?density=compact`, and `archive.entryActions.download` checks for hiding nested entry downloads independently from the viewer-level original download |
| Mobile | The filename stays centered, secondary controls collapse into one More action, only the document container scrolls, and heavy renderers remain lazy |
## Language-Aware Samples [#language-aware-samples]
The demo follows the browser language by default. Chinese browsers open the Chinese sample system; other languages open the English sample system. Use `?locale=zh-CN` or `?locale=en-US` for a stable locale; the historical `lang` parameter remains compatible.
The English demo uses public real-world samples for DOCX, PDF, PPTX, XLSX, and buildingSMART IFC4/IFC4.3, plus local lightweight fixtures for Markdown, text, logs, CSV, JSON, TypeScript, JavaScript, GeoJSON, glTF, binary inspection, and archive nesting. The Demo explicitly registers its optional IFC and binary renderers while keeping normal presets unchanged. All files and heavy Worker/WASM assets are served from the demo origin so enterprise intranet deployments do not depend on public CDNs at runtime.
The sample library opens next to the active source, expands one group at a time, and uses coordinated dark-mode icon palettes instead of filtering light assets.
## Demo File Handoff Protocol [#demo-file-handoff-protocol]
The main demo and iframe entry share the same file handoff protocol. Prefer `/iframe.html` for customer systems: an explicit `url` enters immersive mode, hiding brand, history, and source controls while retaining the document and the active format toolbar. Clean-URL static hosts can also use `/iframe`. Existing systems that already use `/index.html?from=...&name=...` continue to work with the same `postMessage(Blob)` flow.
URL-based iframe:
```html
```
Blob handoff:
```html
```
`from` must match the parent origin. The demo accepts a `Blob` from that origin, wraps it as a `File` with `name`, and renders it. To keep an older main-demo integration, use `/file-viewer/index.html?from=...&name=...` with the same protocol. For customer delivery, use the GitHub Release asset `file-viewer-v2-*-official-demo-iframe.tar.gz`; it includes `iframe-example.html`, `README.iframe.md`, `iframe-manifest.json`, examples, and offline Worker/WASM/vendor assets.
## Local Demo [#local-demo]
```bash
pnpm install
pnpm dev
```
The Vite dev server serves the main demo. Open `/compare.html` on the same host to test side-by-side preview and the jsdiff-powered extracted-text view. DOCX and text files get aligned lines plus character-level additions and removals. PDF work is staged: it follows the PDF text layer, scanned PDFs need OCR, and an incomplete multi-page text layer stops instead of being presented as a complete diff.
## Production Smoke [#production-smoke]
### Reported-Issue Checks [#reported-issue-checks]
Use the same uploaded bytes as the report, not just a similar sample. The regression suite covers hidden XLS search matches, DOC/DOCX text revisions, and page-relative DOCX cover borders on desktop and narrow screens. It also opens real files inside a resizable Element Plus drawer from cold-installed Vue CLI and React full tarballs, without aliases or application-specific Node polyfills.
```sh
# Source-built Demo, including native file upload and HTML page/source switching.
pnpm verify:closed-issue-regressions
# Against the already-built Demo: CAD pixels/print and XLS main-thread/Worker paths.
pnpm verify:issue-245-cad-output
pnpm verify:issue-227-cfb
pnpm verify:issue-204-resize
pnpm verify:mobile-toolbar
# Cold consumer of already-built package tarballs, with the browser assertions.
PACKED_ISSUE_PACKAGE_DIR=/absolute/path/to/candidate-tarballs pnpm verify:issue-consumer
# Actual mobile Safari taps in an already-booted Xcode iPhone Simulator.
CLOSED_ISSUE_DEMO_URL=http://127.0.0.1:4179 pnpm verify:issue-243-ios
```
For HTML, open `page.html` from the sample library and switch between the styled static page and the original source. For DOC/DOCX revisions, use `docx.reviewMode: 'all'`, `'final'`, or `'original'`; this changes the preview, not the source file. A revised paragraph must show genuine deletion/insertion records, without marking unchanged copies of the same text.
The sample library includes `word-revisions.doc` and `word-cover.docx`, copied byte-for-byte from the redistribution-approved reports. In **More > Settings > Formats > Word**, change **DOC / DOCX text revisions**, then apply. The text-format settings also expose the initial HTML view. No application-code edit is needed to compare the modes.
`word-native-revisions.doc` and `word-native-revisions.docx` were created in Microsoft Word for Mac with Track Changes enabled. They cover company-name replacements, unchanged repeated text, mixed bold runs, tabs, soft line breaks, paragraph merges/splits, and table-cell replacements. In `final` mode, `Case join: JOINED` is one paragraph and the deleted soft break is gone. In `original` mode, the original two paragraphs return and the inserted split is removed. The regression fixtures include Word's separately saved Accept All and Reject All reference files and their SHA-256 hashes. These are synthetic samples, not the missing private attachment from #236; they do not claim coverage of all formatting, comment, move, or table-structure revisions.
For OFD, open `ofd-resource-paths.ofd`. It combines a nested document, an alternate XML namespace prefix, and case differences in ZIP paths. Expect `Invoice resource reference` and a black square image. The regression suite also checks resource-XML directories, `BaseLoc`, parent paths, URI encoding, resource priority, and missing nonessential resources. Missing images or font catalogs must not discard readable text; missing required pages, malformed XML, and invalid JBIG2 must finish loading with an error, not a blank success. This constructed sample is not the unavailable original from #57.
For CAD, open `drawing.dxf`, `samples/apache/blocks_and_tables.dwf`, or `samples/autodesk/house.dwfx`. Compare dark-background source mode with black-on-white monochrome, download PNG/JPEG from the CAD toolbar, export HTML, and print to PDF. Check the output pixels, not just the mode label. Output captures the current view/current DWF page; select Fit before exporting the full drawing. Image downloads retain configured text/image watermarks and respect download/export permissions; an unreadable watermark fails explicitly instead of producing an unmarked image.
In a phone-sized host or narrow dialog, the native component toolbar keeps a compact row with Search, zoom and More. Search opens a separate panel; More reveals output actions. Controls must not overlap at 320px or 390px, and a narrow desktop dialog must use its own width rather than the browser width. Wide hosts keep the inline search field. On iPhone, enter a search, close the keyboard, and tap Next again: the host must not stay scrolled beneath Safari's status area. The boot skeleton must not impose `100vh` minimums on the mounted application.
Recent history stays collapsed until requested, so it does not cover worksheet tabs. The column-resize check uses real pointer dragging, switches sheets, zooms in/out, and disables resizing through Demo settings; a changed cursor alone is not a pass.
The MiniFAT check uses a synthetic legacy XLS with an unused invalid MiniFAT pointer, then exercises main-thread and actual Worker parsing through file upload and last-row search. It is not the private #227 attachment. Do not mark that original report verified until the same file is tested privately; damaged required streams must fail clearly rather than silently dropping cells.
After deployment, repeat the Demo checks against `https://demo.file-viewer.app` using `CLOSED_ISSUE_DEMO_URL`. Check `build-info.json` for the expected clean source commit. On iPhone, verify that the visible PDF content moves on Next/Previous and the controls remain reachable; a changed page counter alone is not a pass. Local results and an npm upload are not evidence that the production Demo has been updated.
The repository keeps browser smoke scripts for the demo and component packages:
```bash
pnpm verify:demo-browser-smoke
pnpm verify:demo-sample-click-regression
pnpm verify:component-browser-smoke
pnpm verify:browser-smoke
```
Use these checks before publishing a release that touches renderers, assets, toolbar behavior, search, print, or sample files.
---
# Local Development (/guide/development)
## Install [#install]
```bash
pnpm install
```
## Common Commands [#common-commands]
| Command | Purpose |
| ----------------------------- | -------------------------------------------------------------------------------------------------------- |
| `pnpm dev` | Run the main demo |
| `pnpm docs:dev` | Run the documentation site |
| `pnpm site:dev` | Run the official site |
| `pnpm build-only` | Build the main demo |
| `pnpm docs:build` | Build documentation |
| `pnpm site:build` | Build the official site |
| `pnpm verify:format-support` | Verify 274 registered extensions (224 stable, 50 experimental) and 47 renderer pipelines stay documented |
| `pnpm verify:renderer-assets` | Verify runtime assets are included in renderer packages and web builds |
| `pnpm verify:browser-smoke` | Run demo and component browser smoke tests |
## Release Gate [#release-gate]
Before publishing packages or deploying production, run the focused checks for the area you changed. Renderer and asset changes should at least pass:
```bash
pnpm build-only
pnpm docs:build
pnpm verify:format-support
pnpm verify:renderer-assets
pnpm verify:smoke-matrix
pnpm verify:npm-install-smoke
```
Use `pnpm verify:migration-gates` for a broader migration gate.
## Batch Release Safety [#batch-release-safety]
The private maintainer checkout builds and freezes the package artifacts once. Local packing uses four workers by default (`FILE_VIEWER_PACK_CONCURRENCY`); registry download and comparison use four (`FILE_VIEWER_REGISTRY_CONCURRENCY`). Both accept 1–8 workers. Reusing an already-built artifact is only valid when its source and dependency inputs are unchanged; it does not replace the frozen-release checks.
The GitHub npm workflow publishes the immutable Release tarballs with trusted publishing. It checks all package identities and integrity hashes before the first upload, then publishes in dependency layers, with up to three uploads and six registry checks at a time. A layer must become visible with matching integrity before dependent packages can start. Failures stop new work and wait for active operations to finish; rerunning the same Release skips only versions whose bytes already match. An authorization failure or registry delay is not a reason to allocate another version.
Compatibility aliases need their own version bump when their exact dependency changes. In particular, reusing an old `msdoc-viewer` version would keep those users on its old DOC renderer even after the other packages are updated. The version-freeze check rejects that plan. Registry verification, cold installs, production Demo checks and the final release postcheck are still required after publishing.
---
# Distribution (/guide/distribution)
## npm Registry [#npm-registry]
Common installs:
```bash
npm install @file-viewer/vue3 @file-viewer/preset-office
# Heavy users / all-format attachment centers:
npm install @file-viewer/vue3-full
# Replace @file-viewer/vue3 with @file-viewer/web / react / vue2.7 / vue2.6 / jquery / svelte for other stacks.
```
Every ecosystem has a matching `*-full` package. Full packages already include `preset-all` and their version-aligned renderer/Worker/WASM/font/vendor payload; do not install or pass another preset. Vite or the included CLI publishes those assets under `/file-viewer/`, including the verified binary-PPT 0.3.4 runtime under `vendor/ppt/`.
Pass the preset through `options.preset` in Webpack, Rspack, Rollup, Umi, classic multi-page apps, or internal component libraries. Vite projects can additionally install and register the plugin:
```bash
npm install -D @file-viewer/vite-plugin
```
Recommended Vite setup:
```ts
fileViewerRenderers({
copyAssets: true
})
```
After registration, the plugin recognizes installed full / `@file-viewer/preset-*` packages, injects the capability layer, and publishes complete full-package assets under `/file-viewer/`. Use single renderer packages plus `formats` only for strict custom cuts.
Common customization boundaries:
| Option | Purpose |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `copyAssets:true` | Recognizes full packages / presets; full packages publish under `/file-viewer/` in dev and production, while standard packages/presets keep root placement; required for full packages |
| `formats` / `renderers` | Generates exact renderer imports when you do not use a preset, or when a preset needs a few extra formats |
| `scan:true` | Reads source hints such as `fileViewerFormats`, `data-file-viewer-formats`, and upload `accept` attributes |
| `preset:'auto'` / `autoPresets:true` | Keeps installed preset auto-activation enabled while `scan:true` is active |
| `inject:false` | Disables auto injection so application code can import `virtual:file-viewer-renderers` and pass `options.renderers` manually |
Registry links:
* [`@file-viewer/core`](https://www.npmjs.com/package/@file-viewer/core)
* [`@file-viewer/web`](https://www.npmjs.com/package/@file-viewer/web)
* [`@file-viewer/vue3`](https://www.npmjs.com/package/@file-viewer/vue3)
* [`@file-viewer/react`](https://www.npmjs.com/package/@file-viewer/react)
* [`@file-viewer/svelte`](https://www.npmjs.com/package/@file-viewer/svelte)
* [`@file-viewer/renderer-word`](https://www.npmjs.com/package/@file-viewer/renderer-word)
* [`@file-viewer/renderer-presentation`](https://www.npmjs.com/package/@file-viewer/renderer-presentation)
* [`@file-viewer/ppt@0.3.4`](https://www.npmjs.com/package/@file-viewer/ppt)
* [`@file-viewer/pptx`](https://www.npmjs.com/package/@file-viewer/pptx)
* [`@file-viewer/preset-lite`](https://www.npmjs.com/package/@file-viewer/preset-lite)
* [`@file-viewer/preset-office`](https://www.npmjs.com/package/@file-viewer/preset-office)
* [`@file-viewer/preset-engineering`](https://www.npmjs.com/package/@file-viewer/preset-engineering)
* [`@file-viewer/preset-all`](https://www.npmjs.com/package/@file-viewer/preset-all)
* [`@file-viewer/vite-plugin`](https://www.npmjs.com/package/@file-viewer/vite-plugin)
File Viewer package metadata points to the public repositories, documentation, issue trackers, Apache-2.0 license, and npm donation URL: [dev.flyfish.group/donate?source=npm](https://dev.flyfish.group/donate?source=npm). The bundled `@file-viewer/ppt` runtime and other dependencies retain their included licenses.
`@file-viewer/core` stays lightweight and does not install Word or presentation engines directly.
Use `@file-viewer/preset-lite`, `@file-viewer/preset-office`, or `@file-viewer/preset-engineering` for product-shaped bundles; use individual renderer packages for the smallest custom install, or `@file-viewer/preset-all` when you want the same full renderer matrix as the official demo.
Presentation routing keeps two standalone engines: PowerPoint 97–2003 `.ppt` uses the Worker/OffscreenCanvas/WASM `@file-viewer/ppt@0.3.4` package, while PPTX/OpenXML uses `@file-viewer/pptx` and its separate Worker. Normal ESM/Vite builds resolve the npm dependency directly. Demo, Full, copy-assets, and CDN/IIFE distributions ship the matching public runtime as one integrity-checked `vendor/ppt/` directory, so `.ppt` works without URL configuration. `pptModuleUrl`, `pptWorkerUrl`, `pptWasmUrl`, and `pptFontUrl` are advanced overrides for custom asset routing. `@file-viewer/ppt` keeps its own included license; the public runtime keeps its visible watermark, and removing that PPT watermark requires commercial authorization.
## GitHub [#github]
Main repository:
* [github.com/flyfish-dev/file-viewer](https://github.com/flyfish-dev/file-viewer)
Suggested discovery topics for the main repository:
```txt
file-viewer, document-viewer, document-preview, file-preview, office-viewer,
pdf-viewer, docx, pptx, xlsx, cad-viewer, drawio, excalidraw, web-component,
vue, react, svelte, typescript, wasm, offline-first, self-hosted
```
When you are ready to update the repository topics:
```bash
gh repo edit flyfish-dev/file-viewer \
--remove-topic cad \
--remove-topic office \
--remove-topic jquery \
--remove-topic ofd \
--add-topic document-preview \
--add-topic file-preview \
--add-topic web-component \
--add-topic self-hosted
```
GitHub currently allows up to 20 repository topics, so treat this list as the main SEO surface.
## Release Downloads [#release-downloads]
GitHub Releases can carry:
* static demo builds
* docs builds
* npm tarballs for offline installs
* component demo builds
* source bundles
* demo GIF or MP4 assets for posts and README embeds
For offline or intranet package installs, download the tarballs and install them through a private registry or direct local paths.
The public GitHub repository keeps source, small release metadata, and lightweight package output in git. Full demo, component demo, docs, and sample-file builds should live in GitHub Releases or Cloudflare Pages deployments instead of expanded top-level directories, so a normal clone stays practical. Use `pnpm release:public -- --expanded-assets` only for one-off delivery or mirror troubleshooting that truly needs expanded static assets.
## Official Demo iframe Artifact [#official-demo-iframe-artifact]
When a customer asks for the official demo build output for iframe integration, use the GitHub Release asset `file-viewer-v2-*-official-demo-iframe.tar.gz`. It does not require installing npm packages in the host application. Extract the whole archive to one static directory and keep `assets/`, `vendor/`, `wasm/`, and `example/` together.
`/iframe.html` is the recommended chrome-free entry, and clean-URL static hosts can also use `/iframe`. `/index.html` keeps the original full demo and remains compatible with the same `url`, `from`, `name`, and `postMessage(Blob)` protocol.
URL-based iframe:
```html
```
Blob handoff from the parent page:
```html
```
`from` must match the parent origin. The demo accepts only a `Blob` from that origin and renders it as the provided `name`. The archive also includes `iframe-example.html`, `README.iframe.md`, and `iframe-manifest.json`; `pnpm release:demo-iframe:pack` and `pnpm verify:demo-iframe-artifact` make this artifact part of the standard release flow.
## Full-Package Runtime Assets [#full-package-runtime-assets]
Full packages carry the renderer matrix and its same-version File Viewer-owned runtime assets. In non-Vite projects, publish that included payload with the Full package CLI:
```bash
npx --no-install file-viewer-copy-assets ./public/file-viewer
```
This copies and verifies Worker, WASM, PDF, CAD, Typst WASM/fonts, SQLite, Archive, binary-PPT 0.3.4, PPTX, Draw\.io, and other renderer assets and writes `flyfish-viewer-assets.json`. Serve the directory from `/file-viewer/`.
Every full package uses `file-viewer/` under the deployment base by default (`/file-viewer/` at the origin root) and automatically points to the PDF.js, DOCX, binary-PPT, PPTX Worker, spreadsheet, CAD, Typst, Draw\.io, SQLite, and Archive assets there. If assets live elsewhere, call `setDefaultFullAssetBaseUrl('/your-prefix/')` during startup; explicit `options.*Url` values keep the highest priority. Direct CDN `web-full`, or an intact deployment of its complete `dist/`, resolves all packaged assets relative to the script URL.
For Cloudflare Pages, edge compression is enabled according to the visitor `Accept-Encoding` header. `scripts/deploy-cloudflare-pages.mjs` also Brotli-compresses oversized WASM files before Direct Upload and writes `Content-Encoding: br`, `Vary: Accept-Encoding`, `Content-Type: application/wasm`, and long-term cache headers into `_headers`. This keeps large assets such as the Typst compiler WASM deployable under the original `.wasm` URL. After deployment, verify the live headers with:
```bash
pnpm verify:cloudflare-compression
```
## Sponsorship [#sponsorship]
File Viewer-authored source and packages produced by this repository remain Apache-2.0 open source; the bundled `@file-viewer/ppt` runtime retains its independent LICENSE and NOTICE, while other dependencies retain their included licenses. Sponsorship helps fund compatibility work, documentation, examples, offline assets, and long-term maintenance:
* [GitHub Sponsors](https://github.com/sponsors/wybaby168) for one-time or recurring contributions
* [WeChat / Alipay](https://dev.flyfish.group/sponsor?source=github) for convenient domestic one-time support
* [Enterprise support](https://dev.flyfish.group/shop) for private deployment, custom compatibility work, and committed response expectations
Sponsorship does not change access to open-source features and does not include a service-level agreement unless a published tier explicitly says otherwise.
---
# Docker Deployment (/guide/docker)
The Docker image serves the static demo build through nginx. It includes the main viewer at `/`, the zero-dependency iframe entry at `/iframe.html`, and the comparison demo at `/compare.html`.
## Run From Docker Hub [#run-from-docker-hub]
```bash
docker run -d \
--name file-viewer \
-p 8080:80 \
flyfishdev/file-viewer:latest
```
Open:
* Main viewer: `http://localhost:8080/`
* iframe embed: `http://localhost:8080/iframe.html?url=/example/word.docx`
* Comparison demo: `http://localhost:8080/compare.html`
* Health check: `http://localhost:8080/healthz`
## Build Locally [#build-locally]
```bash
pnpm docker:build
docker run --rm -p 8080:80 flyfishdev/file-viewer:latest
```
## Multi-arch Publish [#multi-arch-publish]
```bash
docker login
DOCKER_IMAGE=flyfishdev/file-viewer pnpm docker:publish
```
The Docker flow targets `linux/amd64` and `linux/arm64`.
## Offline Notes [#offline-notes]
The image serves static demo assets from itself, including offline Worker, WASM, vendor, and example files. Keep `/iframe.html`, `/assets/*`, `/vendor/*`, and `/example/*` on the same static origin when putting another reverse proxy in front of the container. For native component integrations, still copy viewer runtime assets into your own product deployment with:
```bash
npx --yes file-viewer-copy-assets ./public/file-viewer
```
---
# Ecosystem Packages (/guide/ecosystem)
## Recommended Packages [#recommended-packages]
Standard component packages are intentionally light. Installing `@file-viewer/vue3`, `@file-viewer/react`, `@file-viewer/web`, `@file-viewer/svelte`, `@file-viewer/jquery`, or a Vue 2 package gives you the native ecosystem component, types, controller APIs, and the core foundation. Real format coverage is assembled by presets or individual renderer packages.
| Strategy | Install | Notes |
| ------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- |
| Lightest component entry | `npm i @file-viewer/vue3` | Add format capability only after the component shell is wired |
| Lightweight attachments | `npm i @file-viewer/vue3 @file-viewer/preset-lite` | Text, Markdown, code, image, audio, video; pass the preset through `options.preset` |
| Office document platform | `npm i @file-viewer/vue3 @file-viewer/preset-office` | PDF, Word, Excel, PowerPoint, OFD, RTF, OpenDocument; recommended default for document apps |
| Engineering platform | `npm i @file-viewer/vue3 @file-viewer/preset-engineering` | CAD, 3D, drawing, XMind, Geo, Typst, Archive, Data, EDA |
| Full demo capability | `npm i @file-viewer/vue3 @file-viewer/preset-all` | One-step full capability for demos, admin tools, and internal all-format workbenches |
| Full package | `npm i @file-viewer/vue3-full` | Enables `preset-all` by default, no manual `options.preset` needed |
| CDN full trial | `https://unpkg.com/@file-viewer/web-full@latest/dist/flyfish-file-viewer-web-full.iife.js` | Script-tag validation with lazy renderers and packaged binary-PPT 0.3.4 assets |
| Strict custom cut | `npm i @file-viewer/vue3 @file-viewer/renderer-pdf` | Install one renderer and pass it through `options.renderers` |
## Full Package Asset Contract [#full-package-asset-contract]
Since `2.1.30`, all eight Full packages share one delivery contract. They include and enable `preset-all` together with version-aligned renderer, Worker, WASM, font, Draw\.io, SQLite, and other vendor assets; Vite or the included CLI publishes that payload on the application's own origin. The current layout includes both the integrity-checked binary `.ppt` 0.3.4 runtime and the lazy local EPUB engine with its NOTICE, so neither path needs a runtime CDN.
| Build path | Complete deployment |
| ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Vite | Register `fileViewerRenderers({ copyAssets:true })`; the plugin recognizes the installed Full package and serves/copies all assets in both dev and build |
| Webpack, Vue CLI, Rspack, Rollup, Umi, other bundlers | Run `npx --no-install file-viewer-copy-assets ./public/file-viewer`; the binary is included by the Full package at the same version |
| Script tag / CDN | Use jsDelivr/unpkg directly or deploy the complete `@file-viewer/web-full/dist/` directory; no copy command is required |
Do not install another `preset-all` or a separately versioned asset copier next to a Full package. All Full packages default to `file-viewer/` under the deployment base; use `setDefaultFullAssetBaseUrl('/your-prefix/')` only when your static directory differs.
`options.preset` is the bundler-neutral assembly path. Webpack, Rspack, Rollup, Umi, classic multi-page apps, micro-frontends, and internal component libraries can import a preset explicitly and pass it to the component:
```ts
import officePreset from '@file-viewer/preset-office'
const viewerOptions = {
preset: officePreset,
rendererMode: 'replace'
}
```
Vite projects can additionally install `@file-viewer/vite-plugin` to remove manual imports. Vite plugins still need to be registered once in `vite.config.ts`; after that, `fileViewerRenderers()` or `fileViewerRenderers({ copyAssets:true })` auto-discovers installed `@file-viewer/preset-*` packages and injects the generated virtual module into Vite HTML entrypoints. Components keep `autoRenderers:true` by default, so Vue, React, Svelte, jQuery, and Vanilla JavaScript / Pure Web receive the matching preview capability automatically. `preset-all` is intentionally complete and therefore heavier; production apps should normally prefer `preset-lite`, `preset-office`, `preset-engineering`, or individual renderers.
```ts
// vite.config.ts
import { fileViewerRenderers } from '@file-viewer/vite-plugin'
export default {
plugins: [
fileViewerRenderers({
copyAssets: true
// Installed presets are activated automatically; no hand-written import or renderers prop.
})
]
}
```
| Stack | Standard package | Notes |
| ------------------------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| Core foundation | `@file-viewer/core` | Framework-neutral contracts, browser engine, renderer registry, events, search, zoom, print, export, and asset manifests |
| Binary PPT runtime | `@file-viewer/ppt@0.3.4` | Independently versioned dependency; Full/CDN ships its public `vendor/ppt/` assets, isolated from the PPTX Worker path |
| PPTX engine | `@file-viewer/pptx` | OpenXML presentation parsing with progressive Worker output |
| Word renderer | `@file-viewer/renderer-word` | DOCX/DOC/RTF/ODT renderer plugin that lazy-loads Word engines outside core |
| Lite renderer preset | `@file-viewer/preset-lite` | Text, Markdown, code, image, audio, and video preview lines |
| Office renderer preset | `@file-viewer/preset-office` | PDF, Word, Excel, PowerPoint, OFD, RTF, and OpenDocument preview lines |
| Engineering renderer preset | `@file-viewer/preset-engineering` | CAD, 3D, drawing, XMind, Geo, Typst, Archive, Data, and EDA preview lines |
| Full renderer preset | `@file-viewer/preset-all` | Registers the full lazy renderer set |
| Vite on-demand plugin | `@file-viewer/vite-plugin` | Generates renderer imports from explicit formats or source hints |
| Web Component / Vanilla JS | `@file-viewer/web` | ``, `mountViewer`, IIFE bundle, and asset copy CLI |
| Web Component / Vanilla JS Full | `@file-viewer/web-full` | Complete-matrix Custom Element, IIFE, and imperative mount for script tags and POCs |
| Vue 3 | `@file-viewer/vue3` | Native Vue 3 plugin and component |
| Vue 3 Full | `@file-viewer/vue3-full` | Complete-matrix Vue 3 package with the same component API |
| Vue 2.7 | `@file-viewer/vue2.7` | Native Vue 2.7 component |
| Vue 2.7 Full | `@file-viewer/vue2.7-full` | Complete-matrix package for modern Vue 2 applications |
| Vue 2.6 | `@file-viewer/vue2.6` | Dedicated Vue 2.6 compatibility line |
| Vue 2.6 Full | `@file-viewer/vue2.6-full` | Complete-matrix package for legacy Vue 2.6 applications |
| React 18/19 | `@file-viewer/react` | Native React component and handle APIs |
| React 18/19 Full | `@file-viewer/react-full` | Complete-matrix React package with the same component and hook APIs |
| React 16.8/17 | `@file-viewer/react-legacy` | Legacy React package with the same viewer semantics |
| React 16.8/17 Full | `@file-viewer/react-legacy-full` | Complete-matrix package for old React applications |
| jQuery | `@file-viewer/jquery` | Traditional admin-system integration |
| jQuery Full | `@file-viewer/jquery-full` | Complete-matrix package for classic admin systems |
| Svelte | `@file-viewer/svelte` | Svelte component and action |
| Svelte Full | `@file-viewer/svelte-full` | Complete-matrix Svelte package with the same component and action APIs |
## Renderer Packages [#renderer-packages]
Heavy renderers are split so applications can install only what they need:
* `@file-viewer/renderer-pdf`
* `@file-viewer/renderer-word`
* `@file-viewer/renderer-ofd`
* `@file-viewer/renderer-presentation`
* `@file-viewer/renderer-cad`
* `@file-viewer/renderer-typst`
* `@file-viewer/renderer-archive`
* `@file-viewer/renderer-email`
* `@file-viewer/renderer-epub`
* `@file-viewer/renderer-text`
* `@file-viewer/renderer-image`
* `@file-viewer/renderer-media`
* `@file-viewer/renderer-mindmap`
* `@file-viewer/renderer-geo`
* `@file-viewer/renderer-drawing`
* `@file-viewer/renderer-3d`
* `@file-viewer/renderer-data`
* `@file-viewer/renderer-eda`
Standard component packages depend on the lightweight core foundation by default.
Install only the renderer packages your product needs, use `@file-viewer/preset-lite` / `@file-viewer/preset-office` / `@file-viewer/preset-engineering` for product-shaped bundles, or pass `@file-viewer/preset-all` when you want the complete official demo capability matrix.
For example, PowerPoint preview is provided by `@file-viewer/renderer-presentation`, which routes binary `.ppt` to the native-WASM `@file-viewer/ppt@0.3.4` engine and PPTX/PPTM/POTX/POTM/PPSX/PPSM to the separate `@file-viewer/pptx` Worker engine. Neither engine enters the core-only install.
Style isolation is controlled by the shared `options.styleIsolation` field. Every standard component defaults to Shadow DOM so host global CSS cannot break the viewer. Customize with `--file-viewer-*` tokens plus `::part()`; use `styleIsolation:'none'` only as a legacy light-DOM escape hatch. See [Style Isolation And Customization](/guide/style-isolation).
## Vite Auto Assembly [#vite-auto-assembly]
Use the Vite plugin when your app wants a complete developer experience without hand-writing every renderer import. The default setup auto-discovers installed presets; explicit `formats` and `scan:true` are only needed for strict custom cuts or source-hint driven assembly:
```ts
import { defineConfig } from 'vite'
import { fileViewerRenderers } from '@file-viewer/vite-plugin'
export default defineConfig({
plugins: [
fileViewerRenderers({
copyAssets: true,
chunkStrategy: 'renderer'
})
]
})
```
With `scan: true`, use `preset:'auto'` or `autoPresets:true` when installed presets should remain active while source hints add extra renderers. The scan reads hints such as `fileViewerFormats = ['pdf', 'docx']`, `data-file-viewer-formats="dwg,xmind"`, and upload `accept=".pdf,.xlsx"`.
## 2.1.0 Modular Import Paths [#210-modular-import-paths]
### Minimal import: install exactly the renderer you need [#minimal-import-install-exactly-the-renderer-you-need]
For a PDF-only product:
```bash
npm i @file-viewer/vue3 @file-viewer/renderer-pdf
```
```ts
import { pdfRenderer } from '@file-viewer/renderer-pdf'
const options = {
rendererMode: 'replace',
renderers: [pdfRenderer]
}
```
Replace `@file-viewer/vue3` with `@file-viewer/web`, `@file-viewer/react`, `@file-viewer/svelte`, `@file-viewer/jquery`, `@file-viewer/vue2.7`, or `@file-viewer/vue2.6` for other stacks. The `options` contract remains the same.
### Composed import: choose a product-shaped preset [#composed-import-choose-a-product-shaped-preset]
For an Office document platform:
```bash
npm i @file-viewer/vue3 @file-viewer/preset-office
```
```ts
import officePreset from '@file-viewer/preset-office'
const options = {
rendererMode: 'replace',
preset: officePreset
}
```
Use `preset-lite` for lightweight attachments, `preset-engineering` for CAD / 3D / Typst / EDA / data assets, and `preset-all` for the full sample matrix or all-format admin workbenches. Add `preset:'auto'` or `autoPresets:true` when you also enable `scan:true`, so installed presets and source hints work together. `copyAssets:true` copies Worker, WASM, PDF fonts, CAD, Typst WASM/fonts, Archive, and Data assets into your deployment directory so private intranet deployments do not depend on public CDNs.
## React Legacy [#react-legacy]
React 16.8 and 17 projects use `@file-viewer/react-legacy` or `@file-viewer/react-legacy-full`. They keep the same props, controller, event, renderer, and preset contracts as the current React packages while avoiding a React 18 runtime requirement. See the [React integration guide](/guide/quickstart-react) for the shared API and migration boundary.
## jQuery [#jquery]
Use `@file-viewer/jquery` when a traditional admin system or legacy page already standardizes on jQuery-style plugins:
```bash
npm install @file-viewer/jquery
```
The package exposes a native jQuery integration over the same core options, events, operation guards, search, zoom, print, export, and renderer presets. It does not embed Vue or React.
Use `@file-viewer/jquery-full` for the complete matrix without importing a preset. Vite still uses `copyAssets:true`; non-Vite jQuery builds run the Full package's included `npx --no-install file-viewer-copy-assets ./public/file-viewer` command.
## Svelte [#svelte]
Use `@file-viewer/svelte` for Svelte applications:
```bash
npm install @file-viewer/svelte
```
The Svelte package keeps framework-native props and events while delegating renderer work to `@file-viewer/core` and the selected renderer packages.
Use `@file-viewer/svelte-full` for the complete matrix without importing a preset. SvelteKit/Vite uses `copyAssets:true`; other builds run the Full package's included `npx --no-install file-viewer-copy-assets ./public/file-viewer` command.
## Core API [#core-api]
Use `@file-viewer/core` when building a custom host or a new ecosystem package:
```bash
npm install @file-viewer/core
```
Core is pure TypeScript and owns shared contracts, file source normalization, renderer registration, lifecycle events, operation availability, asset manifests, search/zoom/print/export protocols, and utility APIs. UI-specific behavior belongs in the component package for each framework.
## PPT and PPTX Engines [#ppt-and-pptx-engines]
PowerPoint rendering is available through `@file-viewer/renderer-presentation`. Its lower-level engines keep binary and OpenXML formats separate:
```bash
npm install @file-viewer/ppt@0.3.4 @file-viewer/pptx
```
Use `@file-viewer/ppt` only for PowerPoint 97–2003 `.ppt`, and `@file-viewer/pptx` only for PPTX/OpenXML presentations. Most application teams should use the presentation renderer or `preset-office` instead of calling either engine directly.
## Compatibility Names [#compatibility-names]
| Historical package | Prefer now |
| ---------------------------------- | --------------------- |
| `@flyfish-group/file-viewer-web` | `@file-viewer/web` |
| `@flyfish-group/file-viewer3` | `@file-viewer/vue3` |
| `file-viewer3` | `@file-viewer/vue3` |
| `@flyfish-group/file-viewer` | `@file-viewer/vue2.7` |
| `@flyfish-group/file-viewer-react` | `@file-viewer/react` |
Compatibility packages keep old projects working, but new projects get clearer package names, better npm discoverability, and a cleaner upgrade path with the standard names.
---
# FAQ (/guide/faq)
## The viewer is blank [#the-viewer-is-blank]
Confirm the host container has a stable height and the file has a recognizable extension or explicit `type`.
## Does a Full package require a manual asset copy? [#does-a-full-package-require-a-manual-asset-copy]
Not with Vite, and not when the complete `web-full/dist/` directory is deployed. Full packages include `preset-all`, but complete format support also requires their matching Worker, WASM, font, and vendor files to be published. Version `2.1.30` gives every Full package one supported delivery path:
* Vite: enable `fileViewerRenderers({ copyAssets: true })`; dev and build publish matching full-package assets under `/file-viewer/`.
* Webpack, Vue CLI, and other tools: run the same-version binary included by the full package:
```bash
npx --no-install file-viewer-copy-assets ./public/file-viewer
```
* Custom static prefix: call the full package's `setDefaultFullAssetBaseUrl()` during startup.
* CDN/IIFE: deploying the complete `@file-viewer/web-full/dist/` directory needs no extra copy. An entry-only build can run the included CLI.
Do not install another `preset-all` or asset copier version beside a full package. Then confirm your server returns the correct MIME type for `.wasm`, `.js`, fonts, and JSON manifests. Strict CSP deployments should serve all viewer assets from the same trusted origin.
If a Worker or WASM still fails, inspect its URL: the response must be the real asset, not an SPA HTML fallback with status 200.
## How can I verify the DOCX 0.3.31 fixes are active? [#how-can-i-verify-the-docx-0331-fixes-are-active]
The current Word renderer uses `@file-viewer/docx@0.3.35` in both the main thread and the offline Worker. It includes the Japanese text, VML text box, Apache POI `w:hMerge`, multi-section floating-shape, complex frame, section, positioned-page, revision, paragraph-mark, and soft-break fixes, and blocks external document resources by default.
After upgrading, redeploy the matching viewer assets and confirm the browser requests `vendor/docx/docx.worker.js?file-viewer-docx=0.3.35` (possibly below your `file-viewer/` base) as JavaScript. Do not reuse a Worker from an older package version. If the old layout remains, purge the CDN or service-worker cache and reload the document.
## Why does a full package still say the libarchive Worker did not load? [#why-does-a-full-package-still-say-the-libarchive-worker-did-not-load]
Every full package points Archive, PDF, DOCX, Excel, PPTX, CAD, Typst, Draw\.io, SQLite, and related offline assets to `file-viewer/` under the deployment base by default. For a root deployment, confirm these example URLs return the real JavaScript/WASM files instead of a 404 page or an SPA HTML fallback:
* `/file-viewer/vendor/libarchive/worker-bundle.js`
* `/file-viewer/vendor/libarchive/libarchive.wasm`
If assets do not live at `file-viewer/` under the deployment base, set their location once during startup:
```ts
import { setDefaultFullAssetBaseUrl } from '@file-viewer/react-full'
setDefaultFullAssetBaseUrl('/your-static-prefix/')
```
The compatibility-mode notice does not mean ZIP/TAR/GZIP are unusable. It means the libarchive Worker could not start, so RAR, 7z, encrypted archives, and other libarchive-only formats still need the Worker/WASM assets. ZIP, TAR, and GZIP continue through the compatibility path, and legacy GBK/GB18030 Chinese ZIP entry names stay readable there.
## npm 11 fails with `Cannot read properties of null (reading 'matches')` [#npm-11-fails-with-cannot-read-properties-of-null-reading-matches]
This is usually not a `@file-viewer/*` version mismatch. We verify npm 11.17.0 against a clean registry install and a local tgz dependency-closure install for `@file-viewer/vue3 + @file-viewer/preset-office`.
The message is an npm Arborist crash while building the dependency tree. The most common trigger is a project directory whose `node_modules` was created by pnpm, bun, vlt, or another package manager, followed by `npm install` in the same directory. npm may hit a store-style symlink with a null target and throw this internal `matches` TypeError.
Use one package manager per project and reset the install directory:
```bash
# If the project uses npm
rm -rf node_modules package-lock.json npm-shrinkwrap.json
npm cache verify
npm install
```
```bash
# If the project uses pnpm, keep using pnpm
rm -rf node_modules package-lock.json
pnpm install
```
For offline tgz installs, the top-level tgz still needs all runtime dependencies to resolve from npm, a private registry, or sibling local tarballs. In intranet environments, publish the same-version `@file-viewer/vue3`, the selected preset, its renderer packages, and `@file-viewer/core` to a private registry, or declare the local tgz dependency closure together.
Release verification includes:
```bash
pnpm verify:npm-install-smoke
```
## Can I deploy without public CDNs? [#can-i-deploy-without-public-cdns]
Yes. Runtime assets are designed to be self-hosted. Full packages publish Draw\.io, Typst, CAD, Archive, PDF, DOCX, Spreadsheet, SQLite, and other heavy assets through the Vite plugin or their included same-version `file-viewer-copy-assets` binary; `web-full` can instead deploy its complete `dist/`.
## Why does every format not expose every toolbar action? [#why-does-every-format-not-expose-every-toolbar-action]
Each renderer reports operation availability. Download is usually available, but print, HTML export, search, zoom, page navigation, and text anchors depend on the active renderer.
## Should I use an iframe? [#should-i-use-an-iframe]
No for standard package integrations. Use the native package for your stack. iframe-style demos can still be useful for embedding the full hosted demo, but the core product path is native and debuggable.
---
# Format Fidelity (/guide/format-fidelity)
## High-confidence Preview Lines [#high-confidence-preview-lines]
* PDF, OFD, images, audio, video, Markdown, source code, text, JSON/YAML/TOML/XML/SQL, archives, email, EPUB, Mermaid, Excalidraw, draw\.io, and common Office/OpenDocument files.
* CAD preview is powered by `@flyfish-dev/cad-viewer` through `@file-viewer/renderer-cad`; DWG, DXF, DWF, and DWFx assets stay self-hostable.
* STEP / STP, IGES / IGS, and BREP preview uses a self-hosted OCCT worker, runtime, and WASM module to build renderable meshes locally, with orbit controls, fit-to-view, and unified zoom.
* Word preview uses `@file-viewer/renderer-word` and the self-maintained `@file-viewer/docx` path for readable stream-style DOCX rendering.
* Presentation preview uses `@file-viewer/renderer-presentation` with two isolated native engines: PowerPoint 97–2003 `.ppt` lazy-loads the independently versioned native-WASM `@file-viewer/ppt@0.3.4` runtime, while PPTX/OpenXML lazy-loads `@file-viewer/pptx` and its Worker. Full and CDN/IIFE distributions ship both routes' matching assets; `@file-viewer/ppt` keeps its included license and visible public watermark.
## Structure-first Lines [#structure-first-lines]
Some engineering formats are intentionally conservative:
| Format family | Current behavior |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| OLB / DRA | Safe structure preview for common OrCAD / Allegro containers and readable metadata |
| OAS / OASIS | Readable fixtures render; complex binary OASIS stays structure-index focused until the dedicated layout kernel matures |
| IFC | Optional experimental local visual preview through `@file-viewer/renderer-3d/ifc`, with self-hosted That Open / `web-ifc` assets, fit, selection and property inspection; the official Demo includes IFC4 and IFC4.3 fixtures |
| Streaming Geo3D | Explicit experimental `@file-viewer/renderer-3d/geo3d` path for LAS/LAZ/COPC, GeoTIFF/COG, CityJSON, 3D Tiles and 3TZ. COPC/COG/3D Tiles preserve progressive/range access; TIFF is metadata-sniffed before takeover; 3TZ extraction applies traversal/size/count/duplicate guards. Self-host the decoder assets and validate production dataset sizes; converting LAS/LAZ to COPC and GeoTIFF to COG can improve streaming. |
| 3DM | Signature detection and integration guidance; a dedicated `rhino3dm` renderer is still required for visual preview |
| PlantUML | Offline source/SVG-style preview by default; configure an intranet PlantUML service for full server-rendered SVG |
## Verification [#verification]
Use the built-in checks when the format matrix changes:
```bash
pnpm verify:format-support
pnpm verify:smoke-matrix
pnpm verify:renderer-assets
```
---
# Supported Formats (/guide/formats)
The demo groups representative samples for all 47 preview pipelines. Stable rows require redistributable real-file fixtures and browser assertions; synthetic or renamed fixtures never count as evidence. Experimental rows keep their limits visible.
## Main Preview Pipelines [#main-preview-pipelines]
| Category | Examples |
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Word | `docx`, `docm`, `dotx`, `dotm`, legacy `doc`, `dot`, RTF/ODT; structured stable `wpd`, `wp`, `wp5`, `wp6`, `hwp`, `hwpx` |
| Spreadsheets | `xlsx`, `xlsm`, `xlsb`, `xls`, `xla`, `xlam`, `csv`, `tsv`, `ods`, `fods`, `dbf`; stable high-fidelity `numbers` |
| Presentations | binary `ppt`, `pot`; OpenXML `pptx`, `pptm`, `potx`, `potm`, `ppsx`, `ppsm`; OpenDocument `odp`; stable high-fidelity `key` |
| Apple documents | stable high-fidelity `pages`, `numbers`, and `key` with iWork '09 XML/APXL and modern Snappy/IWA parser paths |
| Layout documents | `pdf`, `ofd`, `typ`, `typst` |
| Archives | `zip`, `7z`, `rar`, `tar`, `gz`, `tgz`, `cab`, `iso`, `apk`, `cbz`, `cbr`, and more |
| Email | `eml`, `msg`, `mbox` |
| Medical images (explicit opt-in) | `dcm`, `dicom` through `@file-viewer/renderer-dicom`; one bounded local Part 10 file, including multi-frame navigation |
| Digital signatures (explicit opt-in) | `p7m`, `p7s`, `p7b`, `p7c`, `pkcs7`, `cms`, `cmsc`, `tsq`, `tsr`, `tst`, `tsd`, `asics`, `scs`, `asice`, `sce`, `ers`, `asc`, `sig`, `pgp`, `gpg`, `jws` through `@file-viewer/renderer-signature` |
| Binary inspection (explicit opt-in) | `bin`, `hex`, `elf`, `exe`, `dll`, `class`, `macho` through `@file-viewer/renderer-binary`; a bounded, read-only byte inspector with no MIME wildcard or specialist-route override |
| Diagrams and mind maps | `xmind`, `drawio`, `dio`, `excalidraw`, `mermaid`, `mmd`, `plantuml`, `puml` |
| CAD and engineering | `dwg`, `dxf`, `dwf`, `dwfx`, `xps`, plus EDA files such as `gds`, `oas`, `oasis`, `olb`, `dra` |
| 3D and geospatial | `gltf`, `glb`, `obj`, `stl`, `ply`, `step`, `stp`, `iges`, `ifc`, `3dm`, `brep`, `geojson`, `kml`, `gpx`, `shp`; opt-in `/geo3d`: `las`, `laz`, `copc`, GeoTIFF/COG, CityJSON, 3D Tiles, `3tz` |
| Text, code, and data | Markdown, source code, logs, JSON, YAML, TOML, SQL, IPYNB, SQLite, WASM, Parquet, Avro |
| Adobe design files (explicit opt-in) | `psd`, `psb`, `pdd`, `psdt`, `ai`, `ait`, `eps`, `ps`, `idml`, `icml`, `idms`, `inx`, `xd`, `indd`, `indt`, `fla`, `xfl`, `ase`, `aco`, `abr`, `csh`, `pat`, `grd`, `asl` through `@file-viewer/renderer-design` |
| Media and assets | Images, SVG, HEIC, audio, video, HLS, and fonts |
## Office and Apple evidence boundary [#office-and-apple-evidence-boundary]
* `xla`, `xlam`, `pot`, `dbf`, and `fb2` have real container fixtures, parser assertions, hashes, and Demo smoke cases. Macro and add-in code is never executed.
* `pages`, `numbers`, and `key` include iWork '09 and modern IWA parser fixtures, bounded ZIP/Snappy/Protobuf parsing in a module Worker, a normalized static scene model, search/text layers, sheet/slide navigation, notes, and explicit encrypted-file detection.
* `pages`, `numbers`, and `key` are **high-fidelity / stable**. The gate covers iWork '09, 2013+, and current Apple 15.3.1 native containers with exact structural assertions, real-browser smoke, and fixed-font visual goldens. Pages/Keynote use a 3% pixel-difference threshold and Numbers uses 5%; Quick Look images remain loading placeholders or explicit limited-preview fallbacks only.
* Stable Apple support means static high fidelity: Keynote animations, transitions, and video are not executed; Numbers reads saved formula results instead of recalculating them; encrypted `iwpv2` files are detected and reported; missing fonts surface substitution information.
* `wpd/wp/wp5/wp6` are **structured / stable**. A checksum-pinned MPL-2.0 libwpd/librevenge WebAssembly Worker extracts text, styles, tables, headers, footers, and notes from licensed genuine WP 4.2, 5.0, 5.1, and 6.x fixtures. Chromium, Firefox, and WebKit smoke the packaged Worker/WASM path; `wp5` and `wp6` remain routing aliases and renamed files do not count as fixture evidence. Macros are never executed, and bounded text is only a runtime fallback.
* The binary inspector is experimental and explicit. It owns only seven binary-oriented extensions, parses a reviewed header catalog in a terminable module Worker, and shows raw bytes when no template matches. PNG, ZIP, WASM, `application/octet-stream`, editing, and user-authored templates are intentionally outside its routing contract.
* `hwp/hwpx` are **structured / stable** with redistributable Apache-2.0 HWP v5 and HWPX fixtures. The gate covers page geometry, inline styles, merged tables, headers, footers, notes, and embedded images in Chromium, Firefox, and WebKit. Encrypted, DRM, and distribution documents are detected and rejected explicitly; rare controls and producer-specific layout constructs remain documented limitations.
The full machine-readable matrix, including containers, levels, status, and limits, is generated from `ecosystem/format-catalog.json` into [`docs/generated/format-catalog.md`](/generated/format-catalog).
## Engineering Renderer Notes [#engineering-renderer-notes]
* Adobe creative files use the explicit `@file-viewer/renderer-design` package. Local module Workers and WASM keep parsing off the main thread and make the path fully self-hostable. Fidelity follows the evidence available in each format: saved PSD/PSB composites and supported layer pixels; a verified PDF-compatible Illustrator surface by default; native AI/AIT PGF/private-source artboards, layers, paths, and bounded Canvas rendering through `illustrator-pgf`; IDML pages; structured InDesign exchange/modern XFL; embedded XD/INDD previews; deterministic resource previews; and experimental PostScript output. Unknown native Illustrator operators remain visible in fidelity diagnostics instead of being discarded, and unsupported gradients, complex text, images, plugins, effects, masks, blending, overprint, and color-management semantics are not claimed as complete reconstruction.
* Word preview uses `@file-viewer/renderer-word`. The package lazy-loads `@file-viewer/docx`, `@file-viewer/doc`, and RTF/OpenDocument helpers only for DOCX/DOC/RTF/ODT files, so core-only and lightweight component installs do not pull Word engines by default. `msdoc-viewer` is a compatibility alias for `@file-viewer/doc`, not a separate parser.
* Legacy DOC keeps separate Latin, East Asian and bidirectional font settings and distinguishes single/multiple, minimum and exact line spacing. Fonts come from the browser's installed fonts and fallbacks, not a public CDN; different installed fonts can still change glyphs and wrapping. The Demo includes the original WPS sales-contract sample. That file contains no tracked revisions, so it must not display invented deletion marks.
* DOCX Worker auto mode requires a known `options.docx.workerUrl`, browser Worker support and a safe page protocol. Full packages supply the asset URL; a lightweight integration without it parses on the main thread rather than requesting a missing Worker. Explicit `worker: true` remains available with correctly deployed assets.
* Spreadsheet preview uses `@file-viewer/renderer-spreadsheet` with `styled-exceljs` and `e-virt-table`. It preserves Office 365 and WPS in-cell images alongside workbook drawing images; double-clicking a rendered image opens a full-size preview that can be dismissed with Escape, the backdrop, or the close button.
* Presentation preview uses `@file-viewer/renderer-presentation` with two isolated engines. Binary PowerPoint 97–2003 `.ppt` lazy-loads the packaged `@file-viewer/ppt@0.3.4` Worker/OffscreenCanvas/WASM engine and bounded frame cache; OpenXML files lazy-load `@file-viewer/pptx` and its separate Worker. Standard Demo, Vite/full, copy-assets, and CDN/IIFE layouts need no PPT runtime URL configuration; use `options.presentation.pptModuleUrl` / `pptWorkerUrl` / `pptWasmUrl` / `pptFontUrl` only for custom `.ppt` asset layouts and `workerUrl` / `workerType` for PPTX.
* XMind uses `@file-viewer/renderer-mindmap` with XMind 8 XML and XMind 2020+ JSON package parsing, plus an `@panzoom/panzoom` powered canvas for drag panning, node-start dragging, mobile pinch zoom, keyboard panning, responsive fit-on-open/host-resize behavior, and unified toolbar state sync after pan/navigation.
* Mermaid and PlantUML are handled by `@file-viewer/renderer-drawing`. Mermaid lazy-loads the official `mermaid` renderer and outputs theme-aware SVG. PlantUML stays offline by default with an SVG source preview; configure `options.drawing.plantumlServerUrl` when an intranet PlantUML SVG service is available. If the endpoint is unavailable, the viewer renders the same offline preview instead of leaving the page blank. Both diagram surfaces support drag panning and renderer-native zoom controls through `@panzoom/panzoom`.
* Patch files are rendered with `diff2html` in side-by-side mode. Git bundles parse the bundle header, refs, commit objects, trees, readable blobs, and regular OFS_DELTA / REF_DELTA pack objects directly in the browser; very large packs or bundles that depend on external prerequisites surface a clear boundary notice instead of being silently misrepresented.
* EDA uses `@file-viewer/renderer-eda`. OLB and DRA are safe structure previews over common CFB/OLE2 containers, standard GDSII renders small layouts as SVG and larger element sets through WebGL typed-array batches, readable OASIS text fixtures render as SVG, and real SEMI binary OASIS remains a safe structure-index preview until the dedicated WASM/WebGL layout kernel is split out.
* CAD uses `@file-viewer/renderer-cad` and `@flyfish-dev/cad-viewer`; DWG, DWF, and DWFx assets remain self-hostable for offline deployments.
* Archives use `@file-viewer/renderer-archive` with `libarchive.js` Worker + WASM first, then ZIP/TAR/GZIP compatibility fallback when the Worker cannot start. Legacy ZIP files without the UTF-8 filename flag are decoded with GBK/GB18030 detection so Chinese entry names remain readable in the compatibility path.
* Media uses `@file-viewer/renderer-media` and native browser decoders first. When Chromium rejects an MPEG-4 Part 2 (`mp4v`) Simple Profile track, the renderer loads a dedicated Worker and the Apache-2.0 AOSP PacketVideo decoder. It uses the AAC track as the playback clock and draws decoded I420 frames to a Canvas. The WASM file is 111,379 bytes, or 34,410 bytes with gzip, and loads only after native decoding fails. The implementation contains no FFmpeg, libav, or LGPL/GPL/AGPL source. Files outside the decoder's current coverage get an explicit compatibility notice.
* STEP, IGES, and BREP use the `@file-viewer/renderer-3d` entry plus the lightweight `@file-viewer/geometry-engine` route package and local OpenCascade/WASM decoding. The separate experimental `@file-viewer/renderer-3d/ifc` entry provides self-hosted That Open / Web-IFC preview when explicitly installed, as in the official Demo; it is not added to core, default component installs, or Full packages. 3DM remains signature and conversion guidance pending a dedicated `rhino3dm` path.
* Streaming-first engineering/geospatial datasets use the explicit `@file-viewer/renderer-3d/geo3d` subpath. TIFF is content-sniffed so ordinary `.tif/.tiff` continues to use the image renderer; GeoTIFF/COG is routed only when geographic tags are present. COPC/COG/3D Tiles preserve random-access URLs, while 3TZ extraction is bounded and rejects unsafe archive paths.
## Binary PPT Engine License Boundary [#binary-ppt-engine-license-boundary]
The public `@file-viewer/ppt` build renders `.ppt` files with its required visible watermark and keeps its own package license; it is not covered by File Viewer's Apache-2.0 license. Demo, Full, copy-assets, and CDN/IIFE outputs include its matching public runtime. Removing the PPT watermark requires commercial authorization. The integrity check also requires Web Crypto SHA-256, so deploy this path in a secure browser context (normally HTTPS or localhost).
## Capability Model [#capability-model]
Each renderer reports what it can safely do. The common toolbar then shows download, print, HTML export, zoom, search, and navigation only when the active file type supports those operations.
This avoids pretending that every format supports the same operations. Word and PDF can use full-page print adapters, images can zoom naturally, archives can lazy-extract nested entries, and virtual spreadsheet tables are provided by `@file-viewer/renderer-spreadsheet` to avoid fragile outer CSS scaling.
## Best Evaluation Path [#best-evaluation-path]
1. Open the [live demo](https://demo.file-viewer.app).
2. Try the sample closest to your production files.
3. Test your own file through upload or URL.
4. Use the [comparison demo](https://demo.file-viewer.app/compare.html) for contract, report, and generated-output review.
5. If a standard-package deployment is offline or CSP-restricted, run `npx --yes file-viewer-copy-assets ./public/file-viewer`; Full packages use their included same-version `npx --no-install file-viewer-copy-assets ./public/file-viewer`. Point renderer assets to your own static path.
---
# Docs Home (/guide)
## What To Read First [#what-to-read-first]
| Goal | Page |
| -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| Run the viewer in a project | [Quickstart](/guide/quickstart) |
| Pick the right npm package | [Ecosystem packages](/guide/ecosystem) |
| Embed the official demo without npm packages | [Quickstart: Zero-dependency integration](/guide/quickstart#zero-dependency-integration-official-demo-iframe) |
| Choose minimal imports or composed presets | [2.1.0 modular import paths](/guide/ecosystem#_2-1-0-modular-import-paths) |
| Keep host CSS from leaking into the viewer | [Style isolation and customization](/guide/style-isolation) |
| Check format coverage | [Supported formats](/guide/formats) |
| Understand npm, GitHub, releases, and self-hosted assets | [Distribution](/guide/distribution) |
## Main Links [#main-links]
* Live demo: [demo.file-viewer.app](https://demo.file-viewer.app)
* iframe demo entry: [demo.file-viewer.app/iframe.html?url=/example/en/calibre-demo.docx](https://demo.file-viewer.app/iframe.html?url=/example/en/calibre-demo.docx)
* Document comparison demo: [demo.file-viewer.app/compare.html](https://demo.file-viewer.app/compare.html)
* GitHub repository: [github.com/flyfish-dev/file-viewer](https://github.com/flyfish-dev/file-viewer)
* npm scope: [`@file-viewer`](https://www.npmjs.com/search?q=%40file-viewer)
* GitHub Sponsors: [github.com/sponsors/wybaby168](https://github.com/sponsors/wybaby168)
* WeChat / Alipay: [dev.flyfish.group/sponsor?source=github](https://dev.flyfish.group/sponsor?source=github)
* Enterprise support: [dev.flyfish.group/shop](https://dev.flyfish.group/shop)
## Positioning [#positioning]
File Viewer by Flyfish is not trying to replace specialist editors. It gives business products a practical, embedded preview layer for common and uncommon attachments: documents, spreadsheets, slides, PDFs, archives, email, diagrams, CAD drawings, 3D assets, code, logs, media, and data files.
The project keeps a pure TypeScript core under `@file-viewer/core`, split renderer packages for heavier formats, native component packages for Web Components, Vue, React, jQuery, and Svelte, and product-shaped presets for common capability sets.
The 2.1.0 architecture is modular by default: use minimal renderer imports when you need one exact format, or choose `preset-lite`, `preset-office`, `preset-engineering`, or `preset-all` when your product needs a composed capability set. In Vite projects, `@file-viewer/vite-plugin` auto-discovers installed presets and injects the capability layer, so most teams do not hand-write renderer imports.
Every standard component defaults to Shadow DOM so uncontrolled global CSS cannot break the viewer. Theme customization should use `--file-viewer-*` tokens and stable `::part()` surfaces; use `options.styleIsolation:'none'` only for legacy deep overrides.
For heavy users that need everything immediately, use the native Full package. It already includes `preset-all`; do not install or pass another preset:
```bash
npm install @file-viewer/vue3-full
npm install -D @file-viewer/vite-plugin # Vite
```
```ts
fileViewerRenderers({ copyAssets: true })
```
Vite publishes complete assets in both dev and build. Webpack, Vue CLI, Rspack, Rollup, Umi, and other non-Vite projects run the same-version CLI included by the Full package:
```bash
npx --no-install file-viewer-copy-assets ./public/file-viewer
```
Script-tag deployments can publish the complete `@file-viewer/web-full/dist/` directory without a copy step.
---
# Modular And On-demand Renderers (/guide/on-demand-renderers)
The additive v3 `standard` profile, CLI plan, measured closure budget, and full-cutover blockers are documented in [V3 Modular Profiles](/guide/v3-modular-profiles).
## Minimal Import [#minimal-import]
For a PDF-only Vue 3 product:
```bash
npm install @file-viewer/vue3 @file-viewer/renderer-pdf
```
```ts
import { pdfRenderer } from '@file-viewer/renderer-pdf'
const options = {
rendererMode: 'replace',
renderers: [pdfRenderer]
}
```
This path is bundler-neutral and works in Webpack, Rspack, Rollup, Umi, classic multi-page apps, and micro-frontends. Vite projects can add the plugin to generate and inject the renderer import automatically:
```bash
npm install -D @file-viewer/vite-plugin
```
```ts
import { defineConfig } from 'vite'
import { fileViewerRenderers } from '@file-viewer/vite-plugin'
export default defineConfig({
plugins: [
fileViewerRenderers({
formats: ['pdf'],
copyAssets: true,
chunkStrategy: 'renderer'
})
]
})
```
`copyAssets` copies the offline payload that the installed packages provide. `@file-viewer/renderer-pdf` owns `@fontsource-variable/noto-sans-sc` as a runtime dependency, so direct renderer installs and every PDF preset self-host the CJK fallback automatically. `@file-viewer/assets-standard` remains the preferred pre-staged source for the standard profile. If neither source resolves, the installed dependency tree is incomplete and the build fails with an actionable error instead of silently dropping CJK fallback support. `pnpm test:pdf-cjk-font-github-242` verifies both the direct ownership and the required copied font/license payload.
The plugin reads the Vite major installed by the application. Vite 5–7 receive `build.rollupOptions.output.manualChunks`; Vite 8 receives `build.rolldownOptions.output.codeSplitting.groups`. Existing application groups, priorities, array outputs, and `codeSplitting:false` are preserved, so the plugin adds only its stable CodeMirror and renderer groups.
## Presets [#presets]
| Preset | Best for |
| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `@file-viewer/preset-lite` | Text, code, Markdown, image, audio, and video attachments |
| `@file-viewer/preset-standard` | Common Office/PDF/OFD/archive/email/text/media formats without specialist or legacy-heavy capabilities |
| `@file-viewer/preset-office` | PDF, Word, spreadsheet, presentation, OFD, and OpenDocument workflows |
| `@file-viewer/preset-engineering` | CAD, EDA, Typst, archives, email, data, 3D, geo, drawing, and mind maps |
| `@file-viewer/preset-all` | Admin workbenches that need the published compatibility renderer set, including CHM; later specialist capabilities remain explicit |
## Optional Specialist Renderers [#optional-specialist-renderers]
Since 3.1.2, [BPMN diagrams](/guide/bpmn) and [XML validation and transformation profiles](/guide/xml-profiles) are available as explicit opt-ins. Neither is automatically enabled by Full packages.
Adobe design, DICOM, digital-signature inspection, and binary inspection are explicit opt-ins. They are not dependencies of the eight published `@file-viewer/*-full` packages or the frozen `@file-viewer/preset-all` compatibility baseline. This preserves the published Full contract and prevents specialist Worker/WASM, medical-imaging, cryptographic, or binary-analysis dependencies from appearing during an ordinary upgrade.
| Optional renderer | Formats | Direct npm install | CLI selection | What the viewer shows |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Adobe design** (`@file-viewer/renderer-design`) | `.psd`, `.psb`, `.pdd`, `.psdt`, `.ai`, `.ait`, `.eps`, `.ps`, `.idml`, `.icml`, `.idms`, `.inx`, `.xd`, `.indd`, `.indt`, `.fla`, `.xfl`, `.ase`, `.aco`, `.abr`, `.csh`, `.pat`, `.grd`, `.asl` | `npm install @file-viewer/renderer-design` | `npx file-viewer-cli config add psd --write` | Browser-local Worker/WASM previews for saved Photoshop pixels and supported layers; verified PDF-compatible Illustrator plus switchable native PGF artboards/layers/paths through `illustrator-pgf`; IDML and exchange structures; embedded XD/INDD previews; modern XFL; palettes; Photoshop resources; and PostScript. Unsupported native operators and fidelity limits remain explicit. |
| **DICOM** (`@file-viewer/renderer-dicom`) | `.dcm`, `.dicom` | `npm install @file-viewer/renderer-dicom` | `npx file-viewer-cli config add dicom --write` | One local DICOM Part 10 file, including multi-frame navigation, window width/center, zoom, pan, rotation, fit-to-view, and basic metadata. It does not assemble studies or provide PACS/DICOMweb, MPR, segmentation, or diagnosis. |
| **Digital signatures** (`@file-viewer/renderer-signature`) | `.p7m`, `.p7s`, `.p7b`, `.p7c`, `.pkcs7`, `.cms`, `.cmsc`, `.tsq`, `.tsr`, `.tst`, `.tsd`, `.asics`, `.scs`, `.asice`, `.sce`, `.ers`, `.jws`, `.asc`, `.sig`, `.pgp`, `.gpg` | `npm install @file-viewer/renderer-signature` | `npx file-viewer-cli config add p7m --write` | Bounded browser-local inspection of CMS/PKCS#7, selected CAdES data, timestamps, ASiC containers, evidence records, JWS, and public OpenPGP inputs. Parsing, digest, signature, and timestamp results are reported separately. |
| **Binary inspector** (`@file-viewer/renderer-binary`) | `.bin`, `.hex`, `.elf`, `.exe`, `.dll`, `.class`, `.macho` | `npm install @file-viewer/renderer-binary` | `npx file-viewer-cli config add bin --write` | Read-only, browser-local offset/hex/ASCII view with a bounded module Worker, virtual rows, typed values, and a reviewed ELF, PE/COFF, Mach-O, PNG, ZIP, WebAssembly, and Java-class header catalog. It never claims `application/octet-stream` or displaces a dedicated renderer. |
| **Streaming Geo3D** (`@file-viewer/renderer-3d/geo3d`) | `.las`, `.laz`, `.copc`, GeoTIFF/COG, CityJSON, `tileset.json`, `.3tz` | `npm install @file-viewer/renderer-3d @giro3d/giro3d@2.0.5` (add `jszip@3.10.2` for 3TZ) | Manual subpath registration | Explicit Giro3D-powered streaming/range preview. Ordinary TIFF stays on the image renderer unless GeoTIFF tags are detected; COPC/COG/3D Tiles keep progressive URL access; 3TZ extraction is bounded and path-safe. Copy self-hosted decoder assets with `npx file-viewer-geo3d-assets public/file-viewer/vendor/geo3d`. |
DICOM installations, including CLI `--profile full`, need the application's root dependency overrides and Node.js requirements described in the packaged [DICOM installation policy](https://github.com/flyfish-dev/file-viewer/blob/main/packages/renderers/dicom/README.en.md#application-installation-policy). The default dependency graph still has audit findings; the workspace policy is not inherited by consumers. Qualify the resulting application and browser behavior before deployment.
### I already use a Full package. How do I enable an optional renderer? [#i-already-use-a-full-package-how-do-i-enable-an-optional-renderer]
The same rule applies to `@file-viewer/web-full`, `@file-viewer/vue3-full`, `@file-viewer/vue2.7-full`, `@file-viewer/vue2.6-full`, `@file-viewer/react-full`, `@file-viewer/react-legacy-full`, `@file-viewer/jquery-full`, and `@file-viewer/svelte-full`.
Keep the Full package installed, then add only the specialist renderer the application needs. The following example enables five specialist renderers; remove any package, import, and array entry that the application does not need:
```bash
npm install @file-viewer/renderer-binary @file-viewer/renderer-design @file-viewer/renderer-dicom @file-viewer/renderer-signature @file-viewer/renderer-3d @giro3d/giro3d@2.0.5
```
```ts
import { binaryRenderer } from '@file-viewer/renderer-binary'
import { designRenderer } from '@file-viewer/renderer-design'
import { dicomRenderer } from '@file-viewer/renderer-dicom'
import { signatureRenderer } from '@file-viewer/renderer-signature'
import { createGeo3dRenderer } from '@file-viewer/renderer-3d/geo3d'
const geo3dRenderer = createGeo3dRenderer({
assetBaseUrl: '/file-viewer/vendor/geo3d/',
})
const options = {
rendererMode: 'extend',
renderers: [binaryRenderer, designRenderer, dicomRenderer, signatureRenderer, geo3dRenderer]
}
```
`rendererMode: 'extend'` keeps the preset supplied by the Full package and appends these renderers. Use `replace` only when the explicitly configured renderers should become the complete set.
#### CLI-managed projects [#cli-managed-projects]
Run any relevant `config add` commands, then install the resulting plan:
```bash
# Adobe design
npx file-viewer-cli config add psd --write
# DICOM
npx file-viewer-cli config add dicom --write
# Digital-signature containers
npx file-viewer-cli config add p7m --write
# Binary inspection
npx file-viewer-cli config add bin --write
npx file-viewer-cli install --yes
```
Use `npx file-viewer-cli list` to inspect the current catalog before changing a project.
> Directly installing a Full package and selecting the CLI `full` profile are intentionally different. A Full package keeps the published `preset-all` compatibility baseline. The CLI `full` profile keeps that package and defaults to the established DICOM/signature additions; Adobe design and binary inspection are added only when `config add`, `--formats`, or `--capabilities` explicitly selects them, after their weight and license boundaries are shown.
### Using a prebuilt `web-full` browser bundle? [#using-a-prebuilt-web-full-browser-bundle]
The downloadable `web-full` IIFE bundle contains the published Full renderer set. Adobe design, DICOM, digital-signature, and binary-inspector renderers are not embedded in that bundle.
Use a package-manager project or the File Viewer CLI when the integration needs an optional renderer. Copying a renderer package next to the prebuilt bundle does not register it.
The digital-signature renderer can pass safely extracted PDF, XML, image, Office, or other supported content back through the nested-renderer pipeline, so keep the matching normal renderer available when that preview is required. Cryptographic verification does not establish certificate or key trust, qualified-signature status, policy compliance, or legal validity.
### Binary inspector boundary [#binary-inspector-boundary]
Use the binary inspector only when an application explicitly asks for byte-level inspection. It has no MIME wildcard route and does not replace PNG, ZIP, WASM, or other specialist renderers. The first catalog is read-only and bounded to a 16 MiB whole-file default, 5 seconds of parsing, 512 structure nodes, 16 levels of nesting, and 4 KiB decoded strings; over-limit input fails clearly instead of doing a partial arbitrary scan. A one-shot module Worker parses each input and terminates after a result, error, timeout, or cancellation. The hex grid virtualizes rows, so large accepted inputs do not create one DOM node per byte.
## Renderer Package Reference [#renderer-package-reference]
Install a single renderer when a product needs the smallest possible capability set:
| Renderer package | Export | Main pipeline |
| ------------------------------------ | ---------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `@file-viewer/renderer-pdf` | `pdfRenderer` | PDF |
| `@file-viewer/renderer-word` | `wordRenderer` | DOCX, DOC, DOT, RTF, ODT |
| `@file-viewer/renderer-spreadsheet` | `spreadsheetRenderer` | Excel, OpenDocument spreadsheet, CSV-like tables |
| `@file-viewer/renderer-pptx` | `pptxRenderer` | Modern OpenXML PowerPoint without the legacy PPT runtime |
| `@file-viewer/renderer-ppt` | `pptRenderer` | Optional legacy binary `.ppt` / `.pot` runtime |
| `@file-viewer/renderer-presentation` | `presentationRenderer` | Compatibility aggregate for both PowerPoint families |
| `@file-viewer/renderer-ofd` | `ofdRenderer` | OFD |
| `@file-viewer/renderer-cad` | `cadRenderer` | DWG, DXF, DWF, DWFx, XPS |
| `@file-viewer/renderer-3d` | `modelRenderer` | 3D models and lightweight geometry signatures |
| `@file-viewer/renderer-design` | `designRenderer` | PSD/PSB/PDD/PSDT, AI/AIT, EPS/PS, IDML/ICML/IDMS/INX, XD, INDD/INDT, modern FLA/XFL, ASE/ACO, and ABR/CSH/PAT/GRD/ASL |
| `@file-viewer/renderer-dicom` | `dicomRenderer` | Selected local DICOM Part 10 single-file and multi-frame preview in the standard Viewer entry |
| `@file-viewer/renderer-signature` | `signatureRenderer` | Selected CMS/CAdES, timestamp, ASiC, evidence-record, JWS, and public OpenPGP inspection in the standard Viewer entry |
Binary PowerPoint and OpenXML PowerPoint now have separate npm renderer packages. The compatibility aggregate keeps the existing root and subpath APIs. The packaged `.ppt` 0.3.4 runtime is zero-config in layouts that explicitly install it; for custom asset layouts, configure `presentation.pptModuleUrl` / `pptWorkerUrl` / `pptWasmUrl` / `pptFontUrl`. PPTX continues to use `presentation.workerUrl` / `workerType`.
Strict PPTX-only applications should import `pptxRenderer` from `@file-viewer/renderer-pptx`, or configure `fileViewerRenderers({ formats: ['pptx'] })`. Both paths exclude the classic `.ppt` package, font, and WASM from the install and production closure. Existing `@file-viewer/renderer-presentation/pptx` imports remain compatible. The binary-only package is `@file-viewer/renderer-ppt`.
\| `@file-viewer/renderer-drawing` | `drawingRenderer` | draw\.io, Excalidraw, Mermaid, PlantUML |
\| `@file-viewer/renderer-mindmap` | `mindmapRenderer` | XMind |
\| `@file-viewer/renderer-geo` | `geoRenderer` | GeoJSON, KML, GPX, SHP |
\| `@file-viewer/renderer-typst` | `typstRenderer` | Typst source rendered through local WASM assets |
\| `@file-viewer/renderer-archive` | `archiveRenderer` | Archives and nested file preview |
\| `@file-viewer/renderer-chm` | `chmRenderer` | CHM contents, index, search, internal links, and local Rust/WASM topic extraction |
\| `@file-viewer/renderer-email` | `emailRenderer` | EML, MSG, MBOX |
\| `@file-viewer/renderer-epub` | `ebookRenderer` | EPUB, UMD |
\| `@file-viewer/renderer-text` | `textRenderer` | Markdown, highlighted code, patch, git bundle |
\| `@file-viewer/renderer-image` | `imageRenderer` | Image and HEIC / HEIF paths |
\| `@file-viewer/renderer-media` | `mediaRenderer` | Audio, video, HLS, MIDI summaries |
\| `@file-viewer/renderer-data` | `dataRenderer` | PSD, fonts, SQLite, Parquet, Avro, WASM, WebArchive |
\| `@file-viewer/renderer-eda` | `edaRenderer` | OLB, DRA, GDS, OAS/OASIS |
Engine packages such as `@file-viewer/pptx`, `@file-viewer/geometry-engine`, `@file-viewer/eda-layout`, and `@file-viewer/eda-orcad` are maintained for renderer internals and advanced reuse. Normal viewer integrations should use the renderer or preset package above.
### CHM with a self-hosted Rust/WASM Worker [#chm-with-a-self-hosted-rustwasm-worker]
Install the standalone renderer when an application only needs Compiled HTML Help:
```bash
npm install @file-viewer/vue3 @file-viewer/renderer-chm
```
```ts
import { chmRenderer } from '@file-viewer/renderer-chm'
const options = {
rendererMode: 'replace',
renderers: [chmRenderer]
}
```
Vite projects can instead select `formats: ['chm']` with `copyAssets:true`. `preset-all` and the Full packages already include the renderer, but the deployment must still publish these version-matched files under `file-viewer/vendor/chm/`:
* `chm.worker.js`
* `chm_wasm.js`
* `chm_wasm_bg.wasm`
The Vite plugin and the same-version asset copy CLI publish that directory automatically. A custom asset layout can override it with `options.chm.workerUrl`, `options.chm.wasmModuleUrl`, and `options.chm.wasmUrl`; do not point production deployments at a public CDN.
The archive is parsed locally in a dedicated Worker. Topic HTML is sanitized before display and rendered in an iframe sandbox without `allow-scripts`; a restrictive CSP also disables scripts, plugins, forms, base-URL rewriting, and automatically loaded remote active content. Internal `ms-its:` / `mk:@MSITStore` links and packaged resources are resolved back into the current CHM instead of receiving network access. This is a read-only documentation viewer, not an ActiveX-compatible HTML Help runtime.
## Automatic Preset Assembly [#automatic-preset-assembly]
For an Office document platform, the bundler-neutral path is:
```bash
npm install @file-viewer/vue3 @file-viewer/preset-office
```
```ts
import officePreset from '@file-viewer/preset-office'
const options = {
rendererMode: 'replace',
preset: officePreset
}
```
`@file-viewer/vite-plugin` can discover installed presets and inject the generated virtual module into the Vite HTML entry. In Vite projects, add the plugin once and the framework component automatically receives that preview capability without a manual preset import:
```bash
npm install -D @file-viewer/vite-plugin
```
```ts
fileViewerRenderers({
copyAssets: true
// No preset option required: installed @file-viewer/preset-* packages are discovered.
})
```
`inject` defaults to true. Preset packages register themselves in core when imported, and `FileViewerOptions.autoRenderers` defaults to true in normal `extend` mode. Set `autoRenderers:false` only when a product needs full manual control.
The default experience is intentionally zero-config: if the plugin receives no explicit `preset`, `formats`, or `renderers`, or only receives `copyAssets:true`, it auto-discovers installed `@file-viewer/preset-*` packages. `preset-all` takes precedence when present; otherwise installed `lite`, `office`, and `engineering` presets are composed.
Install `@file-viewer/preset-all` when an application needs the published compatibility baseline. Adobe design, DICOM, digital signatures, and binary inspection remain explicit:
```bash
npm install @file-viewer/vue3 @file-viewer/preset-all
# Vite projects add the plugin:
npm install -D @file-viewer/vite-plugin
```
Use `preset:'auto'` or `autoPresets:true` when you also enable `scan:true`; this keeps installed preset discovery active while source hints add extra renderers. If `preset-all` is installed, it takes precedence to avoid importing narrower presets twice.
```ts
fileViewerRenderers({
preset: 'auto',
scan: true,
formats: ['pdf'],
copyAssets: true,
chunkStrategy: 'renderer'
})
```
| Customization | Purpose |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| `copyAssets:true` | Copies matched Worker, WASM, font, PDF/CAD/Typst/Archive/CHM/Data, and vendor assets, including the three files under `vendor/chm/` |
| `preset:'auto'` / `autoPresets:true` | Keeps installed preset auto-discovery active together with `scan:true` |
| `formats` / `renderers` | Adds a few formats outside a preset, or builds a strict single-renderer bundle |
| `scan:true` | Collects format hints from `fileViewerFormats`, `data-file-viewer-formats`, `accept`, and similar source hints |
| `inject:false` | Disables auto injection so application code imports `virtual:file-viewer-renderers` and passes `options.renderers` manually |
| `chunkStrategy:'renderer'` | Uses renderer-level chunk names for caching and heavy-pipeline size debugging |
## Manual Control [#manual-control]
Strict bundles can still use the virtual module directly:
```ts
fileViewerRenderers({
formats: ['pdf'],
inject: false,
copyAssets: true
})
```
```ts
import { configuredFileViewerRenderers } from 'virtual:file-viewer-renderers'
const options = {
rendererMode: 'replace',
renderers: configuredFileViewerRenderers
}
```
`scan:true` detects hints such as `fileViewerFormats`, `data-file-viewer-formats`, and upload `accept` attributes, then merges them with explicit `formats`.
## Missing Renderer Guidance [#missing-renderer-guidance]
If a file extension is in the supported matrix but its renderer has not been assembled, the viewer shows a friendly install-oriented state. For example, opening `.pdf` without the PDF renderer recommends `@file-viewer/preset-office` or `@file-viewer/renderer-pdf`. Only extensions outside the matrix are shown as truly unsupported.
## Asset Rules [#asset-rules]
Use `copyAssets:true` or `npx --yes file-viewer-copy-assets ./public/file-viewer` for standard-package offline deployments. Full packages include the matching CLI and use `npx --no-install file-viewer-copy-assets ./public/file-viewer`. Worker, WASM, font, PDF, CAD, Typst, Archive, CHM, Data, and Draw\.io assets should be served from your own domain. A CHM deployment is complete only when `vendor/chm/chm.worker.js`, `vendor/chm/chm_wasm.js`, and `vendor/chm/chm_wasm_bg.wasm` are available with JavaScript and WebAssembly MIME types.
## CHM Completion Checklist [#chm-completion-checklist]
* [x] `@file-viewer/renderer-chm` is available as a standalone renderer and is included by `preset-all` / Full packages.
* [x] The Rust/WASM parser runs in a dedicated Worker, and standard asset tooling self-hosts the Worker, JavaScript bridge, and WASM binary under `vendor/chm/`.
* [x] Contents, keyword index, text search, internal navigation, and packaged resources stay within the current archive.
* [x] Topic documents are sanitized, scripts remain disabled by sandbox and CSP, and remote active content is not loaded automatically.
## Optional streaming Geo3D viewer [#optional-streaming-geo3d-viewer]
The explicit `@file-viewer/renderer-3d/geo3d` entry adds the streaming-first
geospatial formats without changing the ordinary 3D renderer or any Full preset.
It covers LAS/LAZ/COPC, GeoTIFF/COG, CityJSON, 3D Tiles and bounded 3TZ archives.
Regular TIFF stays on the image renderer unless bounded TIFF metadata inspection
finds GeoTIFF tags. COPC/COG/3D Tiles keep URL/File random-access semantics where
the source format supports them.
Install the optional Giro3D peer and copy its decoder assets locally with
`file-viewer-geo3d-assets`. See
[`GEO3D.md`](https://github.com/flyfish-dev/file-viewer/blob/main/packages/renderers/3d/GEO3D.md)
for detection, range/CORS, 3TZ safety, samples and deployment details.
## Optional IFC BIM viewer [#optional-ifc-bim-viewer]
The explicit `@file-viewer/renderer-3d/ifc` entry enhances only IFC files with
local That Open / Web-IFC visualization, selection, properties and a configuration
hook. Existing Full/Office entry points remain unchanged. Install the optional
peers and self-host their matching Worker/WASM assets with `file-viewer-ifc-assets`.
The exact setup and licensing notes are in the package's [IFC guide](https://github.com/flyfish-dev/file-viewer/blob/main/packages/renderers/3d/IFC.md).
---
# Overview (/guide/overview)
## What It Solves [#what-it-solves]
File Viewer by Flyfish lets users preview business attachments without downloading every file or sending private documents to a conversion backend. It covers Office documents, PDF/OFD, Typst, CAD, EDA, archives, email, diagrams, mind maps, 3D, media, code, and structured data through lazy renderer packages.
The canonical catalog declares **275 registered extensions** across **47 preview pipelines**: **225 stable** and **50 experimental**.
## Architecture [#architecture]
| Layer | Responsibility |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `@file-viewer/core` | Framework-neutral contracts, renderer registry, events, assets, lifecycle, search, zoom, print, export, and shared utilities |
| Renderer packages | Heavy format-specific engines such as PDF, Word, Presentation, CAD, Typst, Archive, Email, EPUB, Drawing, Data, and EDA |
| Presets | Product-shaped renderer bundles: `preset-lite`, `preset-office`, `preset-engineering`, and `preset-all` |
| Component packages | Native integrations for Vanilla JS / Web Component, Vue, React, Svelte, and jQuery |
| Apps | Official site, documentation site, main demo, comparison demo, and component demos |
Core stays pure TypeScript and framework-neutral. Component packages depend on core and expose native APIs for their ecosystem.
## Why Modular [#why-modular]
Most products do not need every heavy engine on first load. Install a minimal renderer set for a focused product, or use a preset when you need broader coverage. Worker, WASM, font, and vendor assets remain self-hostable for intranet and strict-CSP deployments.
The bundler-neutral path is `options.preset` / `options.renderers`: import the preset or renderer package and pass it to the component. In Vite projects, `@file-viewer/vite-plugin` is an optional assembly layer that removes manual imports after one plugin registration. It auto-discovers installed `@file-viewer/preset-*` packages and injects the matching capability registry, so the default Vite setup is still `fileViewerRenderers({ copyAssets:true })`. Use `@file-viewer/preset-all` for the fastest full-capability start, or explicit `formats`, `renderers`, `scan:true`, and `inject:false` only when a product needs strict bundle control.
Every standard component uses Shadow DOM by default so uncontrolled host CSS cannot break the viewer. Theme customization stays stable through `--file-viewer-*` tokens and `::part()`; use `options.styleIsolation:'none'` only for legacy deep overrides. See [Style Isolation And Customization](/guide/style-isolation).
## Main Entry Points [#main-entry-points]
* Official site: [file-viewer.app](https://file-viewer.app)
* Documentation: [doc.file-viewer.app](https://doc.file-viewer.app)
* Live demo: [demo.file-viewer.app](https://demo.file-viewer.app)
* iframe demo entry: [demo.file-viewer.app/iframe.html?url=/example/en/calibre-demo.docx](https://demo.file-viewer.app/iframe.html?url=/example/en/calibre-demo.docx)
* Comparison demo: [demo.file-viewer.app/compare.html](https://demo.file-viewer.app/compare.html)
* GitHub: [github.com/flyfish-dev/file-viewer](https://github.com/flyfish-dev/file-viewer)
---
# React Integration (/guide/quickstart-react)
## Install [#install]
```bash
npm install @file-viewer/react @file-viewer/preset-office
```
Installing only `@file-viewer/react` gives you the lightest React component and core foundation. PDF, Office, CAD, Typst, archive, and other heavy format capabilities come from presets or renderer packages. The stable path for every bundler is to import a preset or renderer and pass it through `options.preset` / `options.renderers`:
```tsx
import officePreset from '@file-viewer/preset-office'
const viewerOptions = {
preset: officePreset,
rendererMode: 'replace',
theme: 'light',
styleIsolation: 'shadow',
toolbar: { position: 'bottom-right' }
}
```
React uses Shadow DOM by default so host global CSS, low-code resets, and micro-frontend styles cannot break the viewer. Use `styleIsolation:'none'` only for legacy deep class overrides. See [Style Isolation And Customization](/guide/style-isolation) for tokens and `::part()` customization.
Vite projects can add the plugin once to avoid manual preset imports. Vite still requires a one-line plugin registration; after that, `fileViewerRenderers({ copyAssets:true })` auto-discovers installed `@file-viewer/preset-*` packages:
```bash
npm install -D @file-viewer/vite-plugin
```
```ts
import { defineConfig } from 'vite'
import { fileViewerRenderers } from '@file-viewer/vite-plugin'
export default defineConfig({
plugins: [
fileViewerRenderers({
copyAssets: true
})
]
})
```
Switch `@file-viewer/preset-office` to `@file-viewer/preset-all` when heavy users need the complete capability set immediately. Non-Vite apps keep passing the preset through `options.preset`; Vite apps keep the same plugin config:
```bash
npm install @file-viewer/react @file-viewer/preset-all
```
Use a full package when you want one package to enable the complete matrix. React 18 / 19 uses `@file-viewer/react-full`; React 16.8 / 17 uses `@file-viewer/react-legacy-full`:
```bash
npm install @file-viewer/react-full
```
```tsx
import FileViewer from '@file-viewer/react-full'
export function Preview() {
return (
)
}
```
`@file-viewer/react-full` and `@file-viewer/react-legacy-full` already include `preset-all`; do not install or pass it again. For complete assets, Vite keeps the plugin configuration above and automatically serves/copies the matching payload in dev and build. CRA, Webpack, Rspack, or other non-Vite builds run the Full package's same-version CLI once for the public directory:
```bash
npx --no-install file-viewer-copy-assets ./public/file-viewer
```
Use `formats`, `renderers`, `scan:true`, `inject:false`, or `chunkStrategy:'renderer'` only when the product needs explicit control. The recommended default remains `fileViewerRenderers({ copyAssets:true })`, with installed presets auto-activated by the plugin.
## Component Usage [#component-usage]
```tsx
import { useRef } from 'react'
import FileViewer, { type FileViewerHandle } from '@file-viewer/react'
import officePreset from '@file-viewer/preset-office'
export function Preview() {
const viewerRef = useRef(null)
return (
console.log(event.type)}
/>
)
}
```
## Legacy React [#legacy-react]
React 16.8 and 17 projects should use:
```bash
npm install @file-viewer/react-legacy
```
The event and options model stays aligned with `@file-viewer/react`.
## Mobile, H5, And React Native WebView [#mobile-h5-and-react-native-webview]
The React component works in mobile browsers and H5 WebViews. Give the host container a stable viewport height, keep `minHeight: 0`, and place the common toolbar at the bottom right so document content stays readable. PDF, Word, PPTX, images, CAD, XMind, Mermaid, PlantUML, and similar renderers fit to the available width first; zoom in/out/reset should go through the viewer controller or built-in toolbar instead of wrapping the rendered content with outer CSS transforms.
```tsx
import FileViewer from '@file-viewer/react'
import officePreset from '@file-viewer/preset-office'
export function MobilePreview() {
return (
)
}
```
React Native cannot mount the DOM component directly. Use a `WebView` that loads an H5 viewer route or an `@file-viewer/web-full` IIFE page, then pass file URLs, authorization tokens, or Blob URLs through your app bridge. Enable JavaScript, DOM Storage, and the download capability in the WebView. For strict CSP or offline intranet deployments, keep using `file-viewer-copy-assets` or `@file-viewer/vite-plugin` with `copyAssets:true` so worker, WASM, font, and vendor assets are served from your own domain.
## Vite And Assets [#vite-and-assets]
For Full packages, Vite uses `fileViewerRenderers({ copyAssets:true })`; non-Vite builds use the included `npx --no-install file-viewer-copy-assets ./public/file-viewer`. Both paths keep matching Worker/WASM/font/vendor assets self-hosted under the deployment base.
---
# Svelte Integration (/guide/quickstart-svelte)
## Install [#install]
Use the standard package when you want a light entry plus an explicit preset:
```bash
npm install @file-viewer/svelte @file-viewer/preset-office
```
Use the full package when you want the complete matrix by default:
```bash
npm install @file-viewer/svelte-full
```
`@file-viewer/svelte-full` enables `@file-viewer/preset-all` automatically while keeping the same component, action, event, and controller APIs.
The package-root default export is the Svelte component. Import actions and lower-level controller helpers only from the explicit `/action` and `/controller` subpaths.
## Component Usage [#component-usage]
```svelte
```
Svelte uses Shadow DOM by default so uncontrolled host CSS cannot break the toolbar or renderer content. Use `styleIsolation:'none'` only for legacy deep class overrides. See [Style Isolation And Customization](/guide/style-isolation) for tokens and `::part()` customization.
The full package only changes the import:
```svelte
```
## Action Usage [#action-usage]
For pages that do not want a component instance, mount the action on any existing container:
```svelte
```
The full-package action uses the matching explicit entry:
```ts
import { fileViewer } from '@file-viewer/svelte-full/action'
```
## Vite Auto Assembly [#vite-auto-assembly]
SvelteKit / Vite projects can register the plugin so installed presets activate automatically and Worker / WASM / font / vendor assets are copied:
```bash
npm install -D @file-viewer/vite-plugin
```
```ts
import { fileViewerRenderers } from '@file-viewer/vite-plugin'
export default {
plugins: [
fileViewerRenderers({
copyAssets: true
})
]
}
```
When `@file-viewer/svelte-full` is installed, this configuration recognizes it and publishes the complete matching asset payload in dev and build. The Full package already includes `preset-all`; do not install or pass another preset. Non-Vite Full builds run the included same-version CLI:
```bash
npx --no-install file-viewer-copy-assets ./public/file-viewer
```
Non-Vite standard-package projects keep using `options.preset` / `options.renderers` explicitly.
---
# Vue 2 Integration (/guide/quickstart-vue2)
> Vue 2 is upstream end-of-life. File Viewer will keep its Vue 2.6/2.7 compatibility packages, but new applications should prefer Vue 3. Security-sensitive legacy applications should also assess the host framework's [GHSA-5j4c-8p2g-v4jx](https://github.com/advisories/GHSA-5j4c-8p2g-v4jx), because no patched Vue 2 release is available.
## Vue 2.7 [#vue-27]
```bash
npm install @file-viewer/vue2.7 @file-viewer/preset-office
```
Installing only `@file-viewer/vue2.7` gives you the lightest native Vue 2.7 component. Add presets or renderer packages for concrete PDF, Office, CAD, Typst, archive, and engineering formats. For Webpack, Rspack, Rollup, Umi, and non-Vite applications, pass the capability through `options.preset`:
```ts
import officePreset from '@file-viewer/preset-office'
const viewerOptions = {
preset: officePreset,
rendererMode: 'replace',
theme: 'light',
styleIsolation: 'shadow',
toolbar: { position: 'bottom-right' }
}
```
Vue 2 uses Shadow DOM by default so aggressive global CSS, low-code resets, and micro-frontend styles cannot break the viewer. Use `styleIsolation:'none'` only for legacy deep class overrides. See [Style Isolation And Customization](/guide/style-isolation) for tokens and `::part()` customization.
Vite projects can add the plugin to avoid manual preset imports. Installing the package alone is not enough because Vite plugins must be registered once; after registration the plugin auto-discovers installed presets:
```bash
npm install -D @file-viewer/vite-plugin
```
```ts
import { defineConfig } from 'vite'
import { fileViewerRenderers } from '@file-viewer/vite-plugin'
export default defineConfig({
plugins: [
fileViewerRenderers({
copyAssets: true
})
]
})
```
```ts
import Vue from 'vue'
import FileViewer from '@file-viewer/vue2.7'
Vue.use(FileViewer)
```
```vue
```
## Vue 2.6 [#vue-26]
```bash
npm install @file-viewer/vue2.6 @file-viewer/preset-office
```
Use the same component API as Vue 2.7. Keep your host container at a fixed or viewport-relative height. Switch `@file-viewer/preset-office` to `@file-viewer/preset-all` when heavy users need the full format matrix in one install:
```bash
npm install @file-viewer/vue2.6 @file-viewer/preset-all
```
Full packages are also available when you want the complete matrix by default: use `@file-viewer/vue2.7-full` for Vue 2.7 and `@file-viewer/vue2.6-full` for Vue 2.6.
```bash
npm install @file-viewer/vue2.7-full
```
```ts
import Vue from 'vue'
import FileViewer from '@file-viewer/vue2.7-full'
Vue.use(FileViewer)
```
`@file-viewer/vue2.7-full` and `@file-viewer/vue2.6-full` already include `preset-all`; do not install or pass it again. With the Vite configuration above, dev and build publish the complete matching assets automatically. Vue CLI, webpack 4, Rspack, Rollup, and other non-Vite projects run the Full package's included same-version CLI:
```bash
npx --no-install file-viewer-copy-assets ./public/file-viewer
```
Use `formats`, `renderers`, `scan:true`, `inject:false`, or `chunkStrategy:'renderer'` only for explicit registry control. Normal projects should keep `fileViewerRenderers({ copyAssets:true })` and let the plugin auto-activate installed presets.
## Vue 2.6 + Vue CLI 3 / webpack 4 [#vue-26--vue-cli-3--webpack-4]
If importing `@file-viewer/preset-office` breaks the build but commenting it out lets the app compile, the Vue 2.6 component is usually not the failing part. The office preset pulls PDF, Word, Excel, PPTX, and OFD renderer dependencies into the bundle; Vue CLI 3 / webpack 4 does not transpile `node_modules` by default and does not understand every package `exports` subpath or `import.meta.url` worker pattern.
The repository includes a standalone runnable demo based on this legacy stack:
```bash
cd examples/vue2.6-cli3-office
npm install
npm run serve
```
On Node 17+, webpack 4 may need:
```bash
NODE_OPTIONS=--openssl-legacy-provider npm run build
```
Prefer copying the demo `vue.config.js` first, then trim it after the customer build is stable. Current `@file-viewer/renderer-pdf` tarballs already isolate the staged PDF.js webpack runtime, so consumer projects must not add a loader for renderer-internal `dist/vendor/pdfjs` paths.
```js
// vue.config.js
const path = require('path')
const resolveApp = value => path.resolve(__dirname, value)
const resolvePackageRoot = packageName => path.dirname(require.resolve(`${packageName}/package.json`))
const resolvePackageFile = (packageName, relativePath) => path.join(resolvePackageRoot(packageName), relativePath)
module.exports = {
transpileDependencies: [
/@file-viewer/,
/pdfjs-dist/,
/e-virt-table/,
/styled-exceljs/
],
configureWebpack: {
resolve: {
alias: {
'@file-viewer/core/assets$': resolvePackageFile('@file-viewer/core', 'dist/assets.js'),
'@file-viewer/core/browser$': resolvePackageFile('@file-viewer/core', 'dist/browser.js'),
'@file-viewer/core/headless$': resolvePackageFile('@file-viewer/core', 'dist/headless.js'),
'@file-viewer/docx$': resolvePackageFile('@file-viewer/docx', 'dist/docx-preview.mjs')
},
extensions: ['.mjs', '.js', '.vue', '.json']
}
}
}
```
The renderer build isolates all four PDF.js runtime bindings (`modules`, `module_cache`, `exports`, and `require`) before publishing the tarball and records the source hash, transform count, and output hash in `dist/vendor/pdfjs/provenance.json`. This prevents PDF.js' inner webpack bootstrap from shadowing webpack 4's host exports. A project that separately imports `pdfjs-dist` source modules still owns compatibility for those direct imports; the File Viewer example uses that package only as a build-time source for copied static assets.
Keep the `@file-viewer/docx` alias too: webpack 4 otherwise prefers the UMD `browser` entry, whose CommonJS exports are lost after Babel transpilation and surface as `@file-viewer/docx did not expose a compatible renderAsync function` when a DOCX is uploaded. The other patch, `build/babel-transform-import-meta-url.cjs`, lets webpack 4 parse the PPTX worker module. The copy script publishes the complete nine-file `@file-viewer/ppt@0.3.4` runtime under `public/file-viewer/vendor/ppt/` together with the PPTX worker. The `serve` env files set `NODE_ENV=production` to avoid Vue CLI 3.1 injecting its HMR client into this legacy preview path.
Then pass the preset and self-hosted asset URLs explicitly:
```js
import officePreset from '@file-viewer/preset-office'
const assetBaseUrl = './file-viewer/'
export const viewerOptions = {
preset: officePreset,
rendererMode: 'replace',
theme: 'light',
styleIsolation: 'shadow',
pdf: {
workerUrl: `${assetBaseUrl}vendor/pdf/pdf.worker.mjs`,
cMapUrl: `${assetBaseUrl}vendor/pdf/cmaps/`,
wasmUrl: `${assetBaseUrl}vendor/pdf/wasm/`,
standardFontDataUrl: `${assetBaseUrl}vendor/pdf/standard_fonts/`
},
docx: {
workerUrl: `${assetBaseUrl}vendor/docx/docx.worker.js`,
workerJsZipUrl: `${assetBaseUrl}vendor/docx/jszip.min.js`
},
presentation: {
pptModuleUrl: `${assetBaseUrl}vendor/ppt/index.mjs`,
pptWorkerUrl: `${assetBaseUrl}vendor/ppt/worker.mjs`,
pptWasmUrl: `${assetBaseUrl}vendor/ppt/ppt-native.wasm`,
pptFontUrl: `${assetBaseUrl}vendor/ppt/ppt-font-cjk.otf`,
workerUrl: `${assetBaseUrl}vendor/pptx/pptx.worker.js`
},
spreadsheet: {
workerUrl: `${assetBaseUrl}vendor/xlsx/sheet.worker.js`
}
}
```
`preset-office` covers PDF, Word, spreadsheets, presentations, OFD, and OpenDocument. It intentionally does not include images or media. Add those renderers explicitly when the application also previews `.jpg` or `.mp4`, or combine the office and lite presets:
```js
import officePreset from '@file-viewer/preset-office'
import { imageRenderer } from '@file-viewer/renderer-image'
import { mediaRenderer } from '@file-viewer/renderer-media'
export const viewerOptions = {
preset: officePreset,
renderers: [imageRenderer, mediaRenderer],
rendererMode: 'replace'
}
```
Those four `ppt*Url` values are only needed because this Vue CLI 3 compatibility example explicitly self-hosts assets from `public/file-viewer/`. The copy command and options file are already wired together; normal Vite/full-package installs publish and resolve the same packaged runtime automatically.
Vue CLI 3 / webpack 4 can keep working for modern browsers. If a project still requires IE11-level output or an old `uglifyjs-webpack-plugin` pass over the full office dependency graph, prefer upgrading the minifier/build chain or isolating the viewer through `@file-viewer/vue2.6-full` or the Web Component IIFE package.
## Historical Package [#historical-package]
`@flyfish-group/file-viewer` remains the compatibility line for Vue 2.7. New projects should prefer `@file-viewer/vue2.7` or `@file-viewer/vue2.6`.
---
# Vue 3 Integration (/guide/quickstart-vue3)
## Install [#install]
```bash
npm install @file-viewer/vue3 @file-viewer/preset-office
```
Switch `@file-viewer/preset-office` to `@file-viewer/preset-all` when you want the complete official demo capability in one install.
```bash
npm install @file-viewer/vue3 @file-viewer/preset-all
```
Use the full package when you want one package to enable the complete matrix by default:
```bash
npm install @file-viewer/vue3-full
```
```ts
import { createApp } from 'vue'
import App from './App.vue'
import FileViewer from '@file-viewer/vue3-full'
createApp(App).use(FileViewer).mount('#app')
```
```vue
```
## Dialogs And Component Teardown [#dialogs-and-component-teardown]
The Vue 3 component can be mounted inside Element Plus dialogs, drawers, route tabs, and `v-if` blocks. When a dialog should release the active document after closing, let the host actually unmount the component. For Element Plus, use `destroy-on-close`:
```vue
console.log(event.reason)"
/>
```
On Vue unmount, the component automatically cancels active loading, destroys the current renderer session, clears the rendered DOM, stops zoom and view-state observers, and emits `unload-complete` with `reason: "component-unmount"`. Host code does not need to clear the inner container manually.
If the dialog only hides the component, for example with `v-show` or without `destroy-on-close`, the viewer instance stays alive and keeps the current document. That is useful when the product wants to preserve reading position. For explicit teardown while keeping the surrounding component alive, call `viewerRef.value?.destroy()` and recreate the viewer component when previewing again.
## Universal Renderer Assembly [#universal-renderer-assembly]
The Vue package stays lightweight. Concrete PDF, Office, CAD, Typst, archive, and engineering capabilities are injected through presets or renderer packages. This path works in Vite, Webpack, Rspack, Rollup, Umi, and internal component libraries:
```ts
import officePreset from '@file-viewer/preset-office'
const viewerOptions = {
preset: officePreset,
rendererMode: 'replace',
theme: 'light',
styleIsolation: 'shadow',
toolbar: { position: 'bottom-right' }
}
```
Vue 3 uses Shadow DOM by default so uncontrolled global CSS, low-code resets, and micro-frontend styles cannot break the viewer. Use `styleIsolation:'none'` only for legacy deep class overrides. See [Style Isolation And Customization](/guide/style-isolation) for CSS tokens and `::part()` customization.
## Register Globally [#register-globally]
```ts
import { createApp } from 'vue'
import App from './App.vue'
import FileViewer from '@file-viewer/vue3'
createApp(App).use(FileViewer).mount('#app')
```
```vue
```
## Local Registration [#local-registration]
```vue
```
## Vite Zero-Config Setup [#vite-zero-config-setup]
Vite projects can add the plugin to assemble renderer imports and copy Worker/WASM assets automatically. Installing the npm package alone does not make Vite run it; register the plugin once in `vite.config.ts`. The plugin discovers installed preset packages, so application code can omit the manual preset import:
```bash
npm install -D @file-viewer/vite-plugin
```
```ts
import { defineConfig } from 'vite'
import { fileViewerRenderers } from '@file-viewer/vite-plugin'
export default defineConfig({
plugins: [
fileViewerRenderers({
copyAssets: true
// Installed @file-viewer/preset-* packages are discovered automatically.
})
]
})
```
When `@file-viewer/vue3-full` is installed, this same configuration recognizes it and publishes the complete matching asset payload in dev and build. The Full package already includes `preset-all`; application code must not install or pass another preset. Vue CLI, Webpack, Rspack, Rollup, and other non-Vite projects run the included same-version CLI instead:
```bash
npx --no-install file-viewer-copy-assets ./public/file-viewer
```
Use `preset:'auto'` or `autoPresets:true` when `scan:true` is also enabled, so installed presets stay auto-activated while source hints add extra formats.
## Compatibility Names [#compatibility-names]
Historical packages remain synchronized:
* `@flyfish-group/file-viewer3`
* `file-viewer3`
New Vue 3 projects should use `@file-viewer/vue3`.
---
# Vanilla JS / Script Tag (/guide/quickstart-web)
## Install [#install]
```bash
npm install @file-viewer/web @file-viewer/preset-office
```
Use the full package when you want the complete matrix immediately:
```bash
npm install @file-viewer/web-full
```
`@file-viewer/web-full` enables the complete format matrix while keeping ``, `mountViewer`, and the same controller APIs. Its CDN / IIFE entry only loads the shell and lazy full preset up front; heavy PDF, Word, Excel, CAD, Typst, archive, and similar renderer bundles are fetched later from `dist/renderers/*.iife.js` when the active file type needs them.
The Full package already includes `preset-all`; do not install or pass another preset. Direct CDN use, or deploying its complete `dist/` directory intact, includes renderer chunks plus Worker/WASM/font/vendor assets and needs no copy command. If a package-aware build emits only the application entry, Vite uses `copyAssets:true`; non-Vite builds use the included same-version CLI shown below.
The historical package name remains synchronized for compatibility:
```bash
npm install @flyfish-group/file-viewer-web
```
## RequireJS (AMD) [#requirejs-amd]
From 3.0.3, Web and Web Full include a separate `.amd.js` entry. Deploy the complete
`@file-viewer/web-full/dist/` directory to your own `/file-viewer/` path, alongside
your locally hosted RequireJS. No bundler, `shim`, remote CDN, or global `define`
override is needed:
```html
```
Leave `.js` off RequireJS `paths`. Module aliases are your choice. Keep `renderers/`,
`vendor/`, and `wasm/` next to the entry: they load lazily from that directory, also
under a deployment subpath. The light `flyfish-file-viewer-web.amd.js` exports the
same shell API but does not include Full renderers. Existing `.iife.js` script-tag
and ESM entries are unchanged; do not load an IIFE as an AMD module.
## Web Component [#web-component]
```html
```
```ts
import { defineFileViewerElement } from '@file-viewer/web'
import officePreset from '@file-viewer/preset-office'
defineFileViewerElement()
const viewer = document.getElementById('viewer') as HTMLElement & {
options: unknown
}
viewer.options = {
preset: officePreset,
rendererMode: 'replace',
theme: 'light',
toolbar: { position: 'bottom-right' }
}
```
Keep the host element or parent container at a stable height. The viewer fills that surface.
## Style Isolation And Theme Customization [#style-isolation-and-theme-customization]
``, `@file-viewer/web-full`, and IIFE entries use Shadow DOM by default to isolate the viewer shell, toolbar, and rendered content. This is the recommended path when the host page has global resets, low-code styles, micro-frontend CSS collisions, or legacy admin CSS. To return to the historical light-DOM behavior, set `style-isolation="none"` explicitly:
```html
```
Use CSS tokens and Shadow Parts for controlled customization:
```css
flyfish-file-viewer {
--file-viewer-toolbar-bg: rgba(255, 255, 255, 0.96);
--file-viewer-button-color: #154b83;
}
flyfish-file-viewer::part(toolbar) {
border-radius: 999px;
}
```
See [Style Isolation And Customization](/guide/style-isolation) for modes, tokens, parts, and hostile CSS verification.
For Vite projects, add `@file-viewer/vite-plugin`. Installing the package alone does not make Vite run it; register the plugin once in `vite.config.ts`. It auto-discovers installed `@file-viewer/preset-*` packages and injects renderers, so both the Custom Element and `mountViewer` receive the matching format capabilities without manually importing the preset:
```bash
npm install -D @file-viewer/vite-plugin
```
```ts
import { defineConfig } from 'vite'
import { fileViewerRenderers } from '@file-viewer/vite-plugin'
export default defineConfig({
plugins: [
fileViewerRenderers({
copyAssets: true
})
]
})
```
Installing only `@file-viewer/web` gives you the lightest native web component. Add a preset or renderer package for PDF, Office, CAD, Typst, archives, and other concrete formats. Heavy users can use the full package or keep the standard package with `preset-all`:
```bash
npm install @file-viewer/web @file-viewer/preset-all
```
Use `formats`, `renderers`, `scan:true`, `inject:false`, or `chunkStrategy:'renderer'` only when the product needs exact registry control. The default path stays `fileViewerRenderers({ copyAssets:true })`, with installed presets auto-activated by the plugin.
## Imperative Mount [#imperative-mount]
### Angular With A Deployment Subpath [#angular-with-a-deployment-subpath]
Use the same Web API from `ngAfterViewInit`, and call `controller.destroy()` in
`ngOnDestroy`. Angular's application builder does not reliably emit Worker files
referenced by dependency JavaScript. With light packages, install
`file-viewer-copy-assets` as a development dependency at the same version as the
viewer packages. Full packages already include this CLI. Copy the installed
resources before `ng build`:
```bash
npx --yes file-viewer-copy-assets public/file-viewer
```
Keep the generated `flyfish-viewer-assets.json` with those files. Include the
`public` directory in the build's existing asset configuration, for example:
```json
{
"baseHref": "/ui/",
"assets": [{ "glob": "**/*", "input": "public", "output": "/" }]
}
```
PPTX discovers its copied Worker relative to the application base, including
`/ui/file-viewer/vendor/pptx/pptx.worker.js`; no `deployUrl`, optimizer exclusion,
application alias or custom Worker factory is needed. An explicit
`presentation.workerUrl` still takes precedence. A missing manifest is a broken
asset deployment, not a supported Angular fallback; the renderer reports it
instead of requesting a guessed `/ui/worker/pptx.worker.js` path.
The maintained example is `apps/component-demo/test/angular-pptx`. Its browser
regression cold-installs packages and checks real slides and Worker MIME in
development and production; it does not replace Worker with a recorder.
### Mount And Clean Up [#mount-and-clean-up]
```ts
import { mountViewer } from '@file-viewer/web'
import officePreset from '@file-viewer/preset-office'
const controller = mountViewer(document.getElementById('viewer')!, {
url: '/files/report.docx',
options: {
preset: officePreset,
rendererMode: 'replace',
theme: 'light',
toolbar: { position: 'bottom-right' },
archive: { cache: true }
},
onEvent(event) {
console.log(event.type, event.payload)
}
})
controller.reload()
```
Use `controller.update(options)` to change the source or runtime options. When
the source input is unchanged, it keeps the current document mounted; call
`controller.reload()` when a fresh render is explicitly required.
With the full package, imperative code does not need to import a preset:
```ts
import { mountViewer } from '@file-viewer/web-full'
const controller = mountViewer(document.getElementById('viewer')!, {
url: '/files/demo.dwg',
options: {
theme: 'light',
toolbar: { position: 'bottom-right' }
}
})
controller.zoomIn()
```
Renderers with continuous zoom also accept Ctrl/⌘ + wheel and two-finger pinch.
Set `options.zoomGestures: false` to disable them; the same zoom permissions and
operation hooks apply to gestures and toolbar buttons.
## Authenticated Files [#authenticated-files]
When the business system must authenticate first, fetch the file in the host page and pass a named `File`:
```ts
const blob = await fetch('/api/files/contract', {
credentials: 'include'
}).then(response => response.blob())
const file = new File([blob], 'contract.pdf', { type: blob.type })
document.querySelector('flyfish-file-viewer')!.file = file
```
## Script Tag Without A Bundler [#script-tag-without-a-bundler]
Use the IIFE bundle for pages that do not run Vite, Webpack, Rspack, Rollup, or another package-aware bundler:
```bash
cp ./node_modules/@file-viewer/web/dist/flyfish-file-viewer-web.iife.js ./public/vendor/file-viewer-web/flyfish-file-viewer-web.iife.js
```
```html
```
The IIFE registers the default custom element and exposes `window.FlyfishFileViewerWeb.mountViewer(container, options)`.
### CDN Full Bundle [#cdn-full-bundle]
For no-build pages that need the complete format matrix without local installation, use the `@file-viewer/web-full` CDN entry. jsDelivr / unpkg distribute the complete IIFE directly from npm and expose `window.FlyfishFileViewerWebFull`. The first script only loads the shell and lazy full preset; PDF, Word, Excel, CAD, Typst, archive, and similar renderers are fetched later from `dist/renderers/*.iife.js` when the active file type needs them. Worker, WASM, font, and vendor assets still resolve relative to the script URL:
```html
```
The Custom Element route uses the same full bundle:
```html
```
The CDN full bundle is ideal for POCs, classic admin pages, and public production pages that want complete capability quickly. For intranet, strict-CSP, fully offline, or private Cloudflare / cdnjs-style static domains, mirror `@file-viewer/web-full/dist` or the assets generated by `file-viewer-copy-assets` to your own CDN. cdnjs.com does not automatically host arbitrary npm packages, so a cdnjs URL only exists after the library is accepted there.
## Offline Assets [#offline-assets]
For intranet or strict-CSP deployments, copy runtime assets into your own public directory:
```bash
# @file-viewer/web-full (same-version CLI included)
npx --no-install file-viewer-copy-assets ./public/file-viewer
# Standard @file-viewer/web deployment
npx --yes file-viewer-copy-assets ./public/file-viewer
```
Run one matching command only for an entry-only or non-Vite npm build; an intact `web-full/dist/` deployment already contains the same payload. The command verifies worker, WASM, PDF, CAD, Typst, Archive, Data, DOCX, Spreadsheet, PPTX, and Draw\.io assets. Runtime options such as `options.pdf.workerUrl`, `options.presentation.workerUrl`, `options.archive.wasmUrl`, `options.docx.workerUrl`, `options.typst.compilerWasmUrl`, and `options.drawing.viewerScriptUrl` can point to self-hosted URLs.
## Internationalization [#internationalization]
The Web Component accepts `locale` as an HTML attribute or JS property. Use `options.messages` / `options.i18n` for custom copy:
```html
```
```ts
const viewer = document.querySelector('flyfish-file-viewer')!
viewer.locale = 'zh-CN'
viewer.options = {
i18n: {
locale: 'zh-CN',
messages: {
'toolbar.print': 'Print document'
}
}
}
```
---
# Quickstart (/guide/quickstart)
## Five-step Integration [#five-step-integration]
| Step | Decision | Fast answer |
| ---- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Pick the component package | Use standard packages such as `@file-viewer/web`, `@file-viewer/vue3`, or `@file-viewer/react` for the lightest entry; Full packages preserve the published compatibility matrix, while later specialist renderers remain explicit. |
| 2 | Pick the capability layer | Standard packages receive `preset-lite`, `preset-office`, `preset-engineering`, or `preset-all` through options; Full packages enable the published compatibility matrix, while later specialist renderers remain explicit additions. |
| 3 | Publish runtime assets | Full packages use `copyAssets:true` with Vite; other build tools run `npx --no-install file-viewer-copy-assets ./public/file-viewer` so every selected capability has its matching Worker/WASM assets. |
| 4 | Pass the source and options | Use `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. |
| 5 | Confirm style isolation | Every standard component defaults to Shadow DOM. Customize with tokens / `::part()` and use `options.styleIsolation:'none'` only for legacy deep overrides. |
This page keeps the shortest runnable paths. See [Component Options](/guide/usage) for the full API, renderer package matrix, toolbar, watermark, print, search, lifecycle, and guard options. See [Style Isolation And Customization](/guide/style-isolation) for Shadow DOM, tokens, and parts. See [Modular Assembly](/guide/on-demand-renderers) 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 [#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 already include `@file-viewer/preset-all`; do not install or pass another preset. Complete npm support also includes matching Worker, WASM, font, and vendor assets: Vite publishes them automatically, while other build tools run the same-version CLI included by every full package. For CDN / script-tag pages, prefer `@file-viewer/web-full`: direct jsDelivr/unpkg usage, or an intact mirror of the complete `dist/` directory, resolves every asset relative to the script URL and needs no copy command.
| Mode | Install | Notes |
| ---------------------- | ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------- |
| Light standard package | `npm i @file-viewer/vue3 @file-viewer/preset-office` | Pick exactly the preset / renderer your product needs |
| Complete full package | `npm i @file-viewer/vue3-full` | Includes `preset-all`; publish runtime assets under `/file-viewer/` for complete support |
| CDN full | `https://unpkg.com/@file-viewer/web-full@latest/dist/flyfish-file-viewer-web-full.iife.js` | No local install, ideal for script-tag validation |
Add a preset or a single renderer package for the file formats your product actually needs:
| Package | Coverage | Best fit |
| --------------------------------- | ----------------------------------------------------------------------- | ----------------------------------------- |
| `@file-viewer/preset-lite` | Text, Markdown, code, image, audio, video | Lightweight attachment preview |
| `@file-viewer/preset-office` | PDF, Word, Excel, PowerPoint, OFD, RTF, OpenDocument | OA, approvals, knowledge bases, contracts |
| `@file-viewer/preset-engineering` | CAD, 3D, drawing, XMind, Geo, Typst, Archive, Data, EDA | Engineering, R\&D, design assets |
| `@file-viewer/preset-all` | Full official demo matrix | Demos and internal all-format workbenches |
| Single renderer | For example `@file-viewer/renderer-pdf` or `@file-viewer/renderer-word` | Minimal 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 [#universal-setup-inject-optionspreset]
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
```
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.
### Complete Setup: Full Packages [#complete-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, with `preset-all` built in and enabled by default. Do not install another preset:
| Ecosystem | Full package | Standard 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
```
```vue
```
Each framework keeps its native integration API; do not copy the Vue component syntax across stacks:
```ts
// Vue 2.7; use @file-viewer/vue2.6-full with Vue 2.6.
import Vue from 'vue'
import FileViewerPlugin from '@file-viewer/vue2.7-full'
Vue.use(FileViewerPlugin)
```
```tsx
import FileViewer from '@file-viewer/react-full'
export const Preview = () =>
```
```svelte
```
```ts
import $ from 'jquery'
import installFileViewer from '@file-viewer/jquery-full'
installFileViewer($)
$('#viewer').fileViewer({ url: '/files/contract.pdf' })
```
Every full package defaults its runtime asset base to `file-viewer/` under the deployment base (`/file-viewer/` at the origin root) and pre-fills Archive, PDF, DOCX, Excel, PPTX, CAD, Typst, Draw\.io, and SQLite asset URLs. Vite projects register the plugin once to publish complete assets in development and production:
```ts
import { fileViewerRenderers } from '@file-viewer/vite-plugin'
export default {
plugins: [fileViewerRenderers({ copyAssets: true })]
}
```
Webpack, Rspack, Rollup, Vue CLI, Umi, and classic multi-page projects run the same-version CLI included by the full package:
```bash
npx --no-install file-viewer-copy-assets ./public/file-viewer
```
The complete `web-full` `dist/` already carries assets and can be deployed without this command; entry-only builds run the included CLI.
Without `file-viewer/` under the deployment base, lightweight formats and a few compatibility paths may still work, but CAD, Typst, RAR/7z/encrypted archives, Draw\.io, SQLite, PDF CMaps/fonts, and similar pipelines are not complete.
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 [#cdn-full-complete-script-tag-trial]
No-build pages can load the full CDN bundle directly. Direct jsDelivr/unpkg usage, or an intact deployment of the complete `dist/` directory under one static prefix, needs no asset copy command. Copying only the entry IIFE is not a complete deployment.
```html
```
The Custom Element route is available as well:
```html
```
### Vite Plugin: Zero-Config Assembly [#vite-plugin-zero-config-assembly]
In Vite projects, standard component packages install one `@file-viewer/preset-*`; full packages already include `preset-all`. Once `fileViewerRenderers({ copyAssets:true })` is registered, it recognizes the installed full package or preset. Full assets publish under `/file-viewer/`; standard packages/presets keep their existing root placement. Application code does not import another preset:
```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.
})
]
}
```
For complete capability, switch to a full package and remove the separate preset:
```bash
pnpm add @file-viewer/vue3-full
pnpm add -D @file-viewer/vite-plugin
```
Use explicit options only when you need customization:
| Option | Best fit |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `copyAssets:true` | Recognizes full packages / presets; full packages publish under `/file-viewer/` in dev and production, while standard packages/presets keep root placement; required for full packages |
| `formats` / `renderers` | Generates exact renderer imports when you do not use a preset, or when a preset needs a few extra formats |
| `scan:true` | Scans source hints such as `fileViewerFormats`, `data-file-viewer-formats`, and upload `accept` attributes |
| `preset:'auto'` / `autoPresets:true` | Keeps installed preset auto-discovery active while `scan:true` is enabled |
| `inject:false` | Disables 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 [#vanilla-javascript--web-component]
```bash
npm install @file-viewer/web @file-viewer/preset-office
```
```html
```
```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 [#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
```
## React [#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 (
)
}
```
React 16.8/17 projects can use `@file-viewer/react-legacy`.
## Locale And Copy [#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 ``.
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 [#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.
## Full-Package Worker And WASM Assets [#full-package-worker-and-wasm-assets]
The renderer matrix alone is not the complete full-package contract. Non-Vite full packages run their included same-version CLI and serve the output from `file-viewer/` under the deployment base:
```bash
npx --no-install file-viewer-copy-assets ./public/file-viewer
```
`web-full` may instead deploy its complete `dist/`, which already contains the assets.
The command verifies PDF, archive, DOCX, spreadsheet, Draw\.io, CAD, Typst, SQLite, Worker, WASM, font, and vendor assets and writes `flyfish-viewer-assets.json`. Use `setDefaultFullAssetBaseUrl()` only when the public URL differs. Direct CDN `web-full`, or an intact mirror of its complete `dist/`, is the no-copy exception.
## Zero-Dependency Integration: Official Demo iframe [#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
```
If the parent page must fetch an authenticated file first, pass the resulting `Blob` to the demo:
```html
```
`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 [#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`.
### Japanese locale [#japanese-locale]
Use `locale: 'ja-JP'` to force Japanese. The default `auto` mode checks the complete `navigator.languages` preference list and selects Japanese for `ja`, `ja-JP`, and other Japanese language tags. Unsupported browser locales fall back to English.
### German locale [#german-locale]
Use `locale: 'de-DE'` to force German. The default `auto` mode checks the complete `navigator.languages` preference list and selects German for `de`, `de-DE`, and other German language tags. Unsupported browser locales fall back to English.
---
# Style Isolation And Customization (/guide/style-isolation)
This model is designed for admin systems, OA portals, low-code platforms, micro-frontends, embedded third-party pages, and products where host CSS is hard to control. The goal is to keep both guarantees at once: aggressive host styles should not break the viewer, while product teams can still customize theme, toolbar, and key surfaces predictably.
## Recommendation [#recommendation]
| Scenario | Recommended path |
| ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| New projects, classic admin pages, script tags, low-code, micro-frontends | Use the component package for your stack. The default `styleIsolation:'auto'` uses Shadow DOM. |
| Vue / React / Svelte / jQuery projects under aggressive host CSS | No extra option is required; their standard packages use the same Shadow DOM boundary. |
| Need controlled inheritance from host fonts or theme variables | Use `styleIsolation:'scoped'`. |
| Legacy projects with deep internal class overrides | Temporarily use `styleIsolation:'none'`, then migrate to tokens and parts. |
iframe is not the recommended core path. It gives stronger process-like isolation, but makes file transfer, printing, search, sizing, event bridges, and offline asset deployment much more complex. File Viewer prefers platform-native Shadow DOM isolation.
## Public API [#public-api]
`FileViewerOptions` exposes one shared field:
```ts
type FileViewerStyleIsolation = 'auto' | 'shadow' | 'scoped' | 'none'
const options = {
styleIsolation: 'shadow',
theme: 'light',
toolbar: { position: 'bottom-right' }
}
```
| Value | Behavior |
| -------- | ------------------------------------------------------------------------------------------------------------------------- |
| `auto` | Default. Web Component, IIFE, Vue, React, Svelte, jQuery, and full packages use Shadow DOM. |
| `shadow` | Creates a ShadowRoot render surface. Styles are injected into the isolated root first, and overlays prefer the same root. |
| `scoped` | Does not create a ShadowRoot. Uses a stable root selector and local resets to limit its impact. |
| `none` | Historical light-DOM behavior for legacy theme CSS or deep overrides. |
The Web Component also supports an attribute:
```html
```
To return to historical behavior:
```html
```
## CSS Tokens [#css-tokens]
Start customization with `--file-viewer-*` CSS variables. They can be placed on the custom element, a business shell, `:root`, or a theme class. Shadow DOM inherits CSS custom properties from the host.
```css
flyfish-file-viewer {
--file-viewer-bg: #f7f9fc;
--file-viewer-text: #172033;
--file-viewer-font: Inter, "Segoe UI", sans-serif;
--file-viewer-toolbar-bg: rgba(255, 255, 255, 0.96);
--file-viewer-toolbar-border: rgba(21, 75, 131, 0.16);
--file-viewer-button-color: #154b83;
--file-viewer-button-hover-bg: rgba(21, 75, 131, 0.08);
--file-viewer-button-radius: 6px;
}
```
| Token | Purpose |
| --------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| `--file-viewer-bg` / `--file-viewer-text` / `--file-viewer-muted` | Shell background, primary text, and muted text |
| `--file-viewer-font` | Viewer shell, toolbar, and state panel font |
| `--file-viewer-border` / `--file-viewer-focus-ring` | Borders and keyboard focus styles |
| `--file-viewer-toolbar-bg` / `--file-viewer-toolbar-border` / `--file-viewer-toolbar-shadow` | Toolbar background, border, and shadow |
| `--file-viewer-toolbar-padding` / `--file-viewer-toolbar-gap` / `--file-viewer-toolbar-radius` | Toolbar spacing and radius |
| `--file-viewer-toolbar-floating-offset` / `--file-viewer-toolbar-floating-padding` | Floating toolbar offset and safe padding |
| `--file-viewer-group-bg` / `--file-viewer-group-border` | Toolbar group background and border |
| `--file-viewer-button-color` / `--file-viewer-button-hover-color` / `--file-viewer-button-disabled-color` | Button text colors |
| `--file-viewer-button-hover-bg` / `--file-viewer-button-radius` | Button hover background and radius |
| `--file-viewer-input-bg` / `--file-viewer-input-color` | Built-in inputs such as search |
| `--file-viewer-z-toolbar` / `--file-viewer-z-floating-toolbar` | Toolbar stacking levels |
## Shadow Parts [#shadow-parts]
When tokens are not enough, target stable surfaces with `::part()`:
```css
flyfish-file-viewer::part(toolbar) {
border-radius: 999px;
}
flyfish-file-viewer::part(button) {
min-width: 32px;
font-weight: 600;
}
flyfish-file-viewer::part(content) {
background: #eef2f7;
}
```
| Part | Current purpose |
| ---------------- | --------------------------------- |
| `host` | Internal Web Component mount node |
| `shell` | Viewer shell |
| `toolbar` | Built-in toolbar container |
| `toolbar-group` | Toolbar button group |
| `toolbar-status` | Toolbar status text |
| `button` | Built-in buttons |
| `input` | Built-in inputs such as search |
| `content` | Renderer content mount area |
Renderer authors and future extensions should keep using stable names such as `state-panel` and `watermark` when exposing state panels and watermark layers. Application code should not rely on `.file-viewer-*` internal classes because those classes are implementation details.
## Framework Packages [#framework-packages]
Vue / React / Svelte / jQuery use the same Shadow DOM boundary by default. The explicit option below is equivalent to `auto` and can be useful when an application wants to lock the policy:
```ts
const viewerOptions = {
styleIsolation: 'shadow',
preset: officePreset,
rendererMode: 'replace',
theme: 'light'
}
```
If the application needs limited inheritance from host CSS without letting global resets pollute document content, use:
```ts
const viewerOptions = {
styleIsolation: 'scoped'
}
```
## Hostile CSS Harness [#hostile-css-harness]
Before release, add an aggressive host-CSS harness once and confirm toolbar, buttons, document content, images, canvases, tables, and SVGs remain usable:
```css
* {
box-sizing: content-box !important;
font-size: 26px !important;
line-height: 3 !important;
}
button,
input,
table,
img,
svg,
canvas,
a,
div {
all: unset !important;
display: block !important;
border: 8px solid red !important;
}
```
Expected behavior:
* With `styleIsolation:'auto'` or `'shadow'`, the standard component toolbar and content stay usable.
* Theme variables set through `--file-viewer-*` still apply.
* `flyfish-file-viewer::part(toolbar)` and similar selectors customize only the intended surface.
* Web Component DOM events remain `bubbles:true` and `composed:true`; framework packages continue to forward their native component events across the Shadow boundary.
## Printing And Export [#printing-and-export]
Under Shadow DOM, print and HTML export collect content and required styles from the current render surface. Format-specific adapters still take precedence for complete-page output, such as PDF and Word. Unreliable pipelines such as virtual spreadsheets, media, and 3D continue to hide print buttons dynamically.
If you maintain a custom renderer:
* Do not inject preview styles into `document.head` or `document.body`.
* Prefer the core render surface and style injection helper.
* Mount lightboxes, menus, and overlays inside `context.surface.shadowRoot` or the current renderer container.
* Use stable `part` names for public customization surfaces instead of exposing temporary classes as API.
## Migration [#migration]
1. Keep the default `auto` for new integrations across all standard component packages.
2. If a legacy project depends on deep class overrides, start with `styleIsolation:'none'`.
3. Move color, font, spacing, and radius overrides to `--file-viewer-*` tokens.
4. Move structural customization to `::part()`.
5. Switch back to `auto` or explicit `shadow`, then run the hostile CSS harness and common-format smoke tests.
---
# Component Options (/guide/usage)
## Minimal Options Shape [#minimal-options-shape]
Standard component packages stay lightweight. Install a component package for your stack, then assemble concrete file-format capability through `options.preset` or `options.renderers`.
```ts
import officePreset from '@file-viewer/preset-office'
export const viewerOptions = {
preset: officePreset,
rendererMode: 'replace',
theme: 'light',
styleIsolation: 'shadow',
ui: {
density: 'compact'
},
toolbar: {
position: 'bottom-right',
download: true,
print: true,
exportHtml: true,
zoom: true
},
watermark: {
text: 'Internal',
opacity: 0.14
},
search: {
maxMatches: 1000,
caseSensitive: false
},
archive: {
cache: true,
workerTimeoutMs: 30000,
entryActions: {
download(entry) {
return entry.path.startsWith('public/')
}
}
},
pdf: {
toolbar: true,
streaming: 'same-origin'
}
}
```
`builtinRenderers` remains available for advanced baseline control and historical compatibility, but normal integrations should start with `preset` or `renderers`.
## Preflight Before Rendering [#preflight-before-rendering]
Call `precheckFileViewerSource()` after file selection when the product must reject an unsupported or obviously malformed file before mounting a viewer. It checks extension capability and validates known PDF, OpenXML / OpenDocument, legacy OLE Office, and RTF signatures or package parts without loading a renderer.
```ts
import { precheckFileViewerSource } from '@file-viewer/core/headless'
const result = await precheckFileViewerSource(file, {
supportedExtensions: ['pdf', 'docx', 'xlsx', 'pptx']
})
if (!result.previewable) {
console.warn(result.status, result.reason, result.missingParts)
}
```
`supported` describes the supplied capability list; `valid` describes the content check. `valid: null` means the format has no lightweight validator or only a URL was supplied, not that a full parse passed. The renderer remains the final authority for malformed content. Blob-backed ZIP/Office files read only ZIP metadata instead of copying the complete file.
## Common Options [#common-options]
| Option area | Purpose |
| ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `theme` | Viewer theme: `light`, `dark`, or `system`. Default is `system`; pass `light` when embedding in a fixed light business UI. |
| `styleIsolation` | Style isolation mode: `auto`, `shadow`, `scoped`, or `none`. With `auto`, every standard component uses Shadow DOM so host CSS cannot break the viewer. Customize with `--file-viewer-*` tokens plus `::part()`; use `none` only for legacy deep overrides. See [Style Isolation And Customization](/guide/style-isolation). |
| `ui.density` | UI chrome density: `comfortable` or `compact`. The default `comfortable` keeps existing spacing; `compact` tightens toolbars, archive lists, nested preview headers, badges, small buttons, and search inputs while keeping document content readable. |
| `preset` | Bundler-neutral preset assembly. Pass the default export from `@file-viewer/preset-lite`, `@file-viewer/preset-office`, `@file-viewer/preset-engineering`, or `@file-viewer/preset-all`; compose with `preset: [officePreset, engineeringPreset]`. `presets` is kept only as a compatibility alias for early 2.x drafts. |
| `renderers` / `rendererMode` | Exact renderer or custom renderer assembly. `rendererMode:'replace'` starts from an empty registry, so `preset` / `renderers` define the active capability set; `extend` appends to the current built-in baseline. |
| `builtinRenderers` | Advanced built-in baseline switch: `all`, `lite`, or `none`. Most quick starts do not need it. |
| `toolbar` | Built-in operation bar visibility, position, grouped actions, key-based items, permission gates, and button-specific guards. The print control stays a single compact button with a dropdown for **Print now** and **Mask & print**. |
| `zoomGestures` | Ctrl/⌘ + wheel and two-finger pinch zoom the document when its renderer supports continuous zoom. Enabled by default; use `false` to disable both, or `{ wheel: false }` / `{ pinch: false }` to disable one. Ordinary scrolling and editable controls retain browser behavior. Gestures respect the same operation permissions and hooks as zoom buttons. |
| `watermark` | Text or image watermark source, opacity, spacing, size, rotation, color, and toggle behavior. Enabled watermarks are included in print output. |
| `search` | Document search, highlighted matches, next / previous navigation, whole-word and case-sensitive behavior. |
| `text` | Set `toolbar: false` to hide the renderer-local metadata bar and `lineNumbers: true` for a copy-safe gutter. `wrapLongLines: true` visually wraps logical lines without changing source bytes and also applies to the bounded large-text view. `prettyPrint: true` lazily formats supported structured text for display with Prettier; a badge and toolbar switch distinguish the formatted representation from the original source. `prettyPrintMaxBytes` limits only formatting and defaults to the effective `virtualizeAboveBytes` value (512 KiB when omitted). Oversized, malformed, or unsupported input falls back without error, after which the existing regular/virtual renderer remains authoritative. Fenced Markdown code is highlighted by its declared language by default; set `markdownHighlight: false` to disable it. Language modules load locally on demand; unknown languages or code beyond the 512 KiB highlighting budget remain source. No `highlightAll()` call is needed inside Shadow DOM. Markdown stays rendered by default; use `markdownVirtualizeAboveBytes` only for exceptionally large source inspection. The legacy `*-full` script-tag IIFE assets do not bundle Prettier, so `prettyPrint` falls back to the original source there. |
| `ai` | Text chunk collection for vectorization, source tracing, source-aware highlighting, and audit workflows. It does not call a cloud model by itself. |
| `archive` | Safe extraction limits, IndexedDB cache behavior, worker timeout, nested preview, and self-hosted libarchive paths. |
| `pdf`, `docx`, `spreadsheet`, `cad`, `typst`, `drawing`, `data`, `binary` | Renderer-specific asset URLs and behavior knobs. |
| `cad.showImageExport` | Show the renderer-local PNG/JPEG buttons, default `true`. Hiding them does not change the shared original-file download button; download and HTML-export permission gates still apply. |
| `presentation.workerUrl` | Optional explicit PPTX Worker URL. Otherwise the renderer discovers the standard copied asset manifest under the application asset base, then retains the package's development fallback. See [Angular integration](/guide/quickstart-web). |
| `hooks` | Load start, load complete, unload start, unload complete, errors, and renderer context callbacks. |
| `beforeOperation` | Global pre-action guard for download, print, export HTML, zoom, and custom operations. |
## Preset And Renderer Matrix [#preset-and-renderer-matrix]
Presets are product-shaped capability bundles. Individual renderers are exact, minimal imports for products that only need a few formats.
| Preset | Included renderers | Typical formats | Best fit |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `@file-viewer/preset-lite` | `renderer-text`, `renderer-image`, `renderer-media` | Markdown, code, text, image, audio, video, HLS, HEIC | Lightweight attachments, tickets, chat, mobile-first surfaces |
| `@file-viewer/preset-office` | `renderer-pdf`, `renderer-word`, `renderer-spreadsheet`, `renderer-presentation`, `renderer-ofd` | PDF, DOC/DOCX/DOT, RTF, ODT, XLS/XLSX/ODS, PPT/PPTX, OFD | OA, approvals, knowledge bases, contracts, archive portals |
| `@file-viewer/preset-engineering` | `renderer-cad`, `renderer-3d`, `renderer-drawing`, `renderer-mindmap`, `renderer-geo`, `renderer-typst`, `renderer-archive`, `renderer-data`, `renderer-eda` | DWG/DXF/DWF, 3D, draw\.io, Excalidraw, Mermaid, PlantUML, XMind, GeoJSON/KML/GPX/SHP, Typst, archives, PSD/SQLite/Parquet, OLB/DRA/GDS/OASIS | Engineering drawings, R\&D attachments, design assets, technical archives |
| `@file-viewer/preset-all` | Published standard renderer set plus low-cost core browser routes | Full standard matrix | Attachment centers, demos, validation environments that do not need an explicit specialist |
Every renderer below can be passed through `options.renderers`:
| Renderer package | Export | Pipeline |
| ------------------------------------ | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@file-viewer/renderer-pdf` | `pdfRenderer` | PDF and PDF-backed AI files |
| `@file-viewer/renderer-word` | `wordRenderer` | DOCX, DOC, DOT, RTF, ODT, OpenDocument |
| `@file-viewer/renderer-spreadsheet` | `spreadsheetRenderer` | XLSX, XLS, ODS, CSV and spreadsheet-like files |
| `@file-viewer/renderer-presentation` | `presentationRenderer` | Binary PPT through `@file-viewer/ppt`; PPTX/PPTM/POTX/POTM/PPSX/PPSM through `@file-viewer/pptx`; both load on demand |
| `@file-viewer/renderer-ofd` | `ofdRenderer` | OFD |
| `@file-viewer/renderer-cad` | `cadRenderer` | DWG, DXF, DWF, DWFx, XPS |
| `@file-viewer/renderer-3d` | `modelRenderer` | GLB, GLTF, OBJ, STL, PLY, FBX, DAE, USD; local OCCT preview for STEP/STP, IGES/IGS, and BREP; explicit specialist subpaths add IFC (`/ifc`) and opt-in streaming Geo3D (`/geo3d`: LAS/LAZ/COPC, GeoTIFF/COG, CityJSON, 3D Tiles, 3TZ) without entering Full presets; 3DM keeps signature and integration guidance |
| `@file-viewer/renderer-drawing` | `drawingRenderer` | draw\.io, Excalidraw, Mermaid, PlantUML |
| `@file-viewer/renderer-mindmap` | `mindmapRenderer` | XMind |
| `@file-viewer/renderer-geo` | `geoRenderer` | GeoJSON, KML, GPX, SHP |
| `@file-viewer/renderer-typst` | `typstRenderer` | Typst source rendered through local WASM assets |
| `@file-viewer/renderer-archive` | `archiveRenderer` | ZIP, RAR, 7Z, TAR, GZ, ISO, APK, CBZ, CBR and nested previews |
| `@file-viewer/renderer-email` | `emailRenderer` | EML, MSG, MBOX |
| `@file-viewer/renderer-epub` | `ebookRenderer` | EPUB, UMD |
| `@file-viewer/renderer-text` | `textRenderer` | Markdown, code, logs, JSON/YAML, patch, git bundle |
| `@file-viewer/renderer-image` | `imageRenderer` | Images, HEIC / HEIF where supported by the renderer |
| `@file-viewer/renderer-media` | `mediaRenderer` | Audio, video, HLS, MIDI summaries |
| `@file-viewer/renderer-data` | `dataRenderer` | PSD, fonts, SQLite, Parquet, Avro, WASM, WebArchive, AI/EPS summaries |
| `@file-viewer/renderer-binary` | `binaryRenderer` | Explicit `.bin`, `.hex`, ELF, PE/COFF, Mach-O, and Java class byte inspection; no MIME wildcard or specialist-route override |
| `@file-viewer/renderer-eda` | `edaRenderer` | OLB, DRA, GDS, OAS/OASIS |
EML and MSG attachments open through the same resolved renderer registry as the parent viewer. React, React Legacy, Vanilla JS, and Web Component integrations do not need a framework-specific nested-preview bridge. With a lightweight component, include the preset or renderer for each attachment type you want to preview (for example, the PDF renderer for PDF attachments); Full packages already include the complete standard registry. Attachment filenames are rendered as text, not HTML.
`@file-viewer/renderer-binary` is intentionally separate from `preset-all` and every Full/Vue 2 closure. Register it with `rendererMode: 'replace'` for a binary-only surface or `extend` alongside a focused preset. Its bounded module Worker defaults to 16 MiB, 5 seconds, 512 nodes, 16 levels, and 4 KiB decoded strings; a raw byte view is the fallback rather than an `application/octet-stream` claim.
`@file-viewer/eda-layout`, `@file-viewer/eda-orcad`, `@file-viewer/geometry-engine`, and `@file-viewer/pptx` are reusable engine packages behind renderers. Advanced teams can use them directly, while normal viewer integrations should install the matching renderer or preset.
## Assembly Decisions [#assembly-decisions]
| Goal | Recommended setup |
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| Non-Vite or maximum bundler compatibility | Import a preset and pass `options.preset`. |
| Vite app with less application code | Install a preset, register `@file-viewer/vite-plugin`, and use `fileViewerRenderers({ copyAssets:true })`. |
| One exact format | Install one renderer and pass `options.renderers: [pdfRenderer]`. |
| Office plus engineering documents | Use `preset: [officePreset, engineeringPreset]`. |
| Supported extension but missing renderer | The viewer shows which preset / renderer to install. |
| Truly unknown extension | The viewer shows an unsupported-format state. |
## Renderer-specific Options [#renderer-specific-options]
| Option | Notes |
| ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `archive.workerUrl` / `archive.wasmUrl` | Self-host libarchive worker / WASM when the default viewer asset location does not match your deployment. |
| `archive.workerTimeoutMs` | Timeout for worker startup, encryption checks, and directory reading; the viewer falls back to ZIP/TAR/GZIP-compatible paths when possible. |
| `archive.cache` | Enables IndexedDB cache for extracted nested files. |
| `archive.maxArchiveSize` / `archive.maxEntryPreviewSize` | Memory and safety limits for archive directory reading and nested preview. |
| `archive.entryActions.download` | Controls the download button shown while previewing a file from inside an archive. Pass `false` to hide it globally, or `(entry) => boolean` to decide by path, extension, size, and other metadata. This only affects nested archive entries; the viewer-level original archive download remains controlled by `toolbar` and operation guards. |
| `docx.worker` | Auto-detects the safest DOCX parsing path by default: HTTP/HTTPS keeps the worker enabled, while Electron `file://`, `about:`, and `data:` documents fall back to the main thread. Explicit `true` / `false` values still take precedence. |
| `docx.workerUrl` / `docx.workerJsZipUrl` | Self-host DOCX worker and JSZip assets. |
| `docx.workerTimeout` | Worker startup timeout. The default is 5000ms so unsupported paths, MIME, CSP, or WebView environments fall back quickly. |
| `docx.progressive` | Lets the renderer yield between batches to improve first content and scroll responsiveness on large documents. |
| `docx.visualPagination` | Optional fixed-height, measured pagination. Continuous flow is the default; it preserves author-inserted page breaks and section boundaries, but does not automatically split long tables or paragraphs. |
| `docx.reviewMode` | Text revisions in DOC and DOCX: `all` (default) keeps insertions underlined and deletions struck through; `final` shows the revised text and `original` shows the text before those changes. Text revisions include tracked tabs, soft breaks, and paragraph marks; removing a paragraph mark joins content within the same text flow or table cell. This does not accept or reject revisions in the source file. |
| `text.htmlView` | Initial HTML/HTM view: `preview` (default) or `source`. The page/source buttons switch views. Preview preserves inline styles and embedded images in an isolated sandbox; scripts, forms, external navigation, and external resources are blocked. This is a static document preview, not a website runtime. |
| `text.encoding` | Decoder for text, code, Markdown, HTML, XML, patch files, and LRC lyrics: `auto` (default), `utf-8`, `utf-16le`, `utf-16be`, `gbk`, `gb18030`, `iso-8859-1`, `iso-8859-2`, `iso-8859-15`, `windows-1250`, `windows-1251`, or `windows-1252`. Auto mode checks a BOM, UTF-16 byte structure, and strict UTF-8 before using `text.fallbackEncoding`. Use an explicit encoding for known legacy sources whose bytes are also valid UTF-8. Browsers decode `iso-8859-1` with the Windows-1252 table, as the WHATWG Encoding Standard requires. |
| `text.fallbackEncoding` | Encoding used after auto detection fails: `utf-8`, `gbk`, `gb18030`, or any single-byte label above. Defaults to `gb18030`, preserving existing GBK support. Set `windows-1252` for Western European legacy files or `windows-1251` for Cyrillic ones. Ignored when `text.encoding` is explicit. Download retains the original bytes. |
| `spreadsheet.worker` | Spreadsheet worker mode. The default `auto` keeps small files on the main-thread compatibility path and automatically tries the worker once file size reaches `spreadsheet.workerAutoThreshold`; explicit `true` / `false` values still take precedence. |
| `spreadsheet.workerAutoThreshold` / `spreadsheet.workerUrl` | Large-file threshold for `worker: 'auto'` in bytes, default 1MB, plus the self-hosted Excel/XLSX worker URL. |
| `spreadsheet.textEncoding` | CSV / TSV encoding override: `auto` (default), `utf-8`, `gbk`, or `gb18030`. Auto mode validates UTF-8 first and otherwise uses the browser GB18030 decoder. |
| `spreadsheet.resizableColumns` | Allows users to drag spreadsheet header edges to inspect truncated text. |
| `spreadsheet.fillViewport` | Excel only; default `false`. Adds empty alphabetic column headers, row numbers and virtual grid cells at the worksheet's default sizes to fill small or empty previews. Recalculates on resize/zoom without changing workbook data, used range, exports, search or content counts. Other spreadsheet formats ignore it. Example: `options: { spreadsheet: { fillViewport: true } }`. |
| `presentation.workerUrl` / `presentation.workerType` | Self-host the `@file-viewer/pptx` worker or override its Worker type for strict CSP, legacy WebViews, or custom static asset routing. |
| `presentation.pptModuleUrl` / `presentation.pptWorkerUrl` / `presentation.pptWasmUrl` / `presentation.pptFontUrl` | Advanced overrides for the packaged PowerPoint 97–2003 `.ppt` 0.3.4 ESM, Worker, WASM, and CJK font asset routes. Demo, Vite/full, copy-assets, and CDN/IIFE builds work without them. |
| `presentation.pptWorker` / `presentation.pptCache` | Select `auto` / required / disabled binary-PPT Worker rendering and configure or disable its bounded IndexedDB frame cache. |
| `pdf.streaming` / `pdf.rangeChunkSize` | Controls URL-based progressive PDF loading and PDF.js range chunk size. |
| `pdf.toolbar` | Shows or hides the PDF renderer's own page / zoom / rotation toolbar. Useful for comparison layouts. |
| `pdf.navigation` / `pdf.defaultNavigationVisible` | Enables the left page / outline navigation pane and initial visibility. |
| `pdf.bbox` | Highlights and focuses one or more PDF regions. Supports normalized ratios, percentages, native PDF points, and OCR pixels with explicit source dimensions. |
| `pdf.workerUrl`, `pdf.cMapUrl`, `pdf.wasmUrl`, `pdf.standardFontDataUrl` | Self-host PDF.js worker, CMap, WASM, and standard font assets. The default worker path is probed first and falls back to the packaged PDF.js handler when unavailable. |
| `cad.wasmPath`, `cad.workerUrl`, `cad.dwfWasmUrl` | Self-host LibreDWG and DWF / DWFx / XPS assets. |
| `cad.renderer` | `auto`, `webgl`, or `canvas2d`; default is `auto`. |
| `cad.workerTimeoutMs` | DWG parsing timeout; `0` disables the limit. |
| `typst.compilerWasmUrl`, `typst.rendererWasmUrl`, `typst.fontAssetsUrl` | Self-host Typst compiler / renderer WASM and bundled fonts. |
| `drawing.viewerScriptUrl` | Same-origin self-hosted diagrams.net / draw\.io viewer script used only when `drawing.preferOfficial` is explicitly enabled. The optional runtime is isolated in a no-same-origin iframe with restrictive CSP and falls back to safe SVG output when it cannot load. |
| `data.sqlWasmUrl` | Self-host SQLite WASM for `.sqlite` previews. |
| `binary.maxFileBytes` / `binary.maxParseMilliseconds` / `binary.maxStructureNodes` / `binary.maxStructureDepth` / `binary.maxStringBytes` | Bound the explicit binary-inspector Worker input, parse time, tree complexity, and decoded strings. Defaults are 16 MiB, 5 seconds, 512 nodes, 16 levels, and 4 KiB. |
## Operation Guard [#operation-guard]
```ts
const options = {
async beforeOperation(context) {
if (context.operation === 'download') {
return await checkPermission(context.source)
}
return true
},
toolbar: {
position: 'bottom-right',
items: {
'zoom-reset': false
},
permissions: {
print: canPrint
}
}
}
```
Built-in operation keys are `download`, `print`, `export-html`, `zoom-in`, `zoom-out`, and `zoom-reset`. `toolbar.items` only controls the built-in toolbar UI, so teams can replace selected buttons with their own native controls. `toolbar.permissions` is a hard gate: a `false` value blocks both the built-in toolbar and direct controller / ref API calls before custom `beforeOperation` hooks run. Returning `false` from any guard cancels the operation.
Print delivery notes:
* `printRenderedHtml()` prints the full rendered document and keeps the current watermark when `options.watermark` is enabled.
* `printWithMask()` opens the page-aware mask and stamp designer. It can draw black cover regions or upload a local PNG, JPEG, WebP, GIF, or SVG stamp, then move, resize, remove, and print it under the watermark. Uploaded files stay in the browser as data URLs. The designer is loaded asynchronously inside core, so installing a component package is enough—no extra subpath alias is required.
* Custom toolbars can call either API directly; `printRenderedHtml({ mask })` also accepts precomputed `regions` and `stamps`. Stamp geometry uses percent `left`, `top`, `width`, and `height`, with optional `pageIndex`, `opacity`, `rotate`, and `alt` fields.
* Export / print HTML inlines ephemeral `blob:` image URLs as portable `data:` URLs, so DOCX figures remain visible after download or in the print window.
* CAD export captures the current camera view / current native DWF page, including WebGL vectors and text overlays. Source mode uses a dark background and adaptive contrast; monochrome uses black lines on white paper. Explicit background options take priority. The native PNG/JPEG downloads retain text/image watermarks, use the owning viewer's download hooks, and require both download and HTML-export permissions. `cad.showImageExport: false` hides those buttons. HTML embeds the PNG and Print supports Save as PDF. Use Fit before exporting a whole drawing; this is not a multi-sheet vector PDF converter.
Component teardown follows the host framework lifecycle. Vue 3 / Vue 2 component unmount, React unmount, Web Component `disconnectedCallback`, Svelte action `destroy`, and jQuery plugin `destroy` all enter the same controller teardown path: active loading is cancelled, the renderer session is destroyed, rendered DOM is cleared, zoom/search/view-state observers are stopped, and `unload-start` / `unload-complete` fire with `reason: "component-unmount"`. In Element Plus `el-dialog destroy-on-close`, route switches, tab closing, or `v-if` removal, host code does not need to clear the viewer container manually.
When the host only hides the viewer, such as `v-show`, a dialog without `destroy-on-close`, or KeepAlive, the active document remains mounted. Use this when preserving reading position is desired. If the product needs explicit teardown while keeping the surrounding component alive, call `destroy()` on the component ref or controller, then recreate the viewer before previewing again.
## Lifecycle Hooks [#lifecycle-hooks]
```ts
const options = {
hooks: {
onLoadStart(context) {
console.log('loading', context.type, context.filename)
},
onLoadComplete(context) {
console.log('loaded', context.rendererId, context.duration)
},
onUnloadStart(context) {
console.log('unloading', context.reason)
},
onUnloadComplete(context) {
console.log('unloaded', context.filename)
}
}
}
```
## Toolbar Customization [#toolbar-customization]
Framework packages expose the same operation model with ecosystem-native customization:
| Stack | Customization style |
| ---------- | ---------------------------------------------------------------------------------------- |
| Vanilla JS | `options.toolbar`, Custom Element properties, `mountViewer(...)`, and controller methods |
| Vue | props, emits, and component refs |
| React | props, callback props, and `ref` handle APIs |
| Svelte | props, events, actions, and bindable references |
| jQuery | plugin options, events, and returned instance methods |
Toolbar buttons should call viewer operations rather than wrapping rendered content with outer CSS transforms. This keeps spreadsheet coordinates, PDF text layers, CAD canvases, and mobile gestures aligned.
The initial zoom label is not assumed to be `100%`. Renderers report the actual scale after first-screen fit, image natural-size loading, PDF / Word layout, container resize, or any internal reflow. Built-in toolbars and `getOperationAvailability()` use the same state to keep `zoomIn`, `zoomOut`, and `zoomReset` accurate. Custom toolbars should sync from `zoom-change` or `getZoomState()` instead of caching their own default percentage.
The percentage baseline follows the renderer's coordinate system. For Word/DOCX, `100%` is the document page's natural CSS size, so `120%` means the layout width multiplied by `1.2`, not the current fit-width result enlarged by another 20%; a mobile fit can therefore start below `100%`. CAD has no useful cross-file CSS physical size, so its `100%` is the most recent fitted camera view and later buttons, wheel input, or pinch gestures report a ratio relative to that view. Do not convert percentages across formats into a paper-scale measurement.
## View State Sync [#view-state-sync]
`initialViewState`, `view-state-change`, `getViewState()`, and `applyViewState()` are designed for projection systems, remote-control displays, side-by-side comparison, and reading-position restore. Every standard renderer path registers a view-state provider. Renderers without a dedicated provider use the generic DOM provider, which records the renderer id, current zoom, and scroll ratios. PDF adds page, page count, rotation, and navigation state. XMind adds sheet index, panX, panY, and zoom. Geo adds map center, zoom, bearing, and pitch. 3D adds camera position, target, and display options. CAD reports the view snapshot exposed by the underlying CAD viewer.
```ts
let lastState = null
const options = {
initialViewState: {
page: 3,
scale: 1.25,
scroll: { topRatio: 0.18 }
}
}
function onEvent(event) {
if (event.type === 'view-state-change') {
lastState = event.payload.state
sendToDisplay(event.payload)
}
}
await displayViewer.applyViewState(lastState, {
source: 'api',
action: 'restore'
})
```
A custom PDF toolbar can read the page snapshot and apply a partial state for previous, next, or page-input navigation:
```ts
const state = viewerRef.value?.getViewState()
const page = Number(pageInput.value)
await viewerRef.value?.applyViewState(
{ page },
{ source: 'api', action: 'page-change' }
)
await viewerRef.value?.applyViewState(
{ page: Math.min((state?.page || 1) + 1, state?.pageCount || 1) },
{ source: 'api', action: 'page-step' }
)
```
For synchronization, send the full `state` snapshot instead of replaying individual button clicks. PDF page changes, zooming, scrolling, XMind panning, Geo map movement, and 3D camera updates all use the same event shape; the display side only needs to call `applyViewState()`. High-frequency projection updates may be coalesced to one snapshot per animation frame, but do not use a trailing-only debounce that waits until scrolling stops.
Use `pdf.bbox` to highlight and focus a region on first load, or replace/clear it dynamically through `applyViewState()`. Pages are one-based. OCR pixel coordinates use `pixel` plus the source image dimensions. Native PDF coordinates use `pdf-point` and default to a bottom-left origin. `ratio` and `percent` default to a top-left origin. A single box or an array is accepted, and highlights stay attached through zoom and rotation.
```ts
const options = {
pdf: {
bbox: {
page: 3,
x: 120,
y: 240,
width: 360,
height: 64,
unit: 'pixel',
sourceWidth: 1440,
sourceHeight: 2036,
label: 'Contract amount'
}
}
}
await viewer.applyViewState({
page: 5,
extra: {
bbox: { page: 5, x: 72, y: 640, width: 220, height: 36, unit: 'pdf-point' }
}
}, { source: 'api', action: 'bbox-focus' })
await viewer.applyViewState(
{ extra: { bbox: null } },
{ source: 'api', action: 'bbox-clear' }
)
```
PDF default assets are probed from the site root (`/vendor/pdf/...`) so Vue Router, React Router, and other deep routes do not accidentally request `vendor/pdf/pdf.worker.mjs` from the current page path. When the static worker is missing or an app server falls back to HTML, the PDF renderer lazy-loads the packaged PDF.js worker handler as a compatibility fallback. Use absolute `pdf.workerUrl`, `pdf.cMapUrl`, `pdf.wasmUrl`, and `pdf.standardFontDataUrl` when deploying under a sub-path, a dedicated static asset domain, or a strict CSP. PPTX uses the `@file-viewer/pptx` worker on demand; set `presentation.workerUrl` and, when necessary, `presentation.workerType` for custom worker routes. Binary `.ppt` uses `@file-viewer/ppt@0.3.4`; standard distributions keep its verified ESM/Worker/WASM/font files together under `vendor/ppt/`. Configure `presentation.pptModuleUrl`, `pptWorkerUrl`, `pptWasmUrl`, and `pptFontUrl` only for a custom layout.
---
# Modular Profiles and Full Compatibility (/guide/v3-modular-profiles)
## Profiles are explicit install contracts [#profiles-are-explicit-install-contracts]
| Profile | Contract | Use it when |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `standard` | Common document, PDF/OFD, modern PPTX, spreadsheet, archive, email, text, image, and media capabilities with selective assets | A new application needs broad everyday coverage without specialist engines |
| `lite` | Text, Markdown/code, image, audio, and video | Attachments are mostly lightweight web formats |
| `office` | The established Office preset and its compatibility formats | An Office-focused integration relies on that exact preset |
| `engineering` | The established engineering preset | The product needs CAD, 3D, EDA, Geo, or related engineering formats |
| `all` | The published `@file-viewer/preset-all` compatibility matrix | A modular application already depends on `preset-all` |
| `full` | The matching historical `@file-viewer/*-full` package plus later explicit opt-ins known by the CLI | Install size is acceptable and the product deliberately wants every catalog capability |
| `custom` | Only the capabilities selected in project config | Dependency ownership must be exact |
The profile controls package installation and renderer registration. Runtime loading remains format-driven: a selected heavy renderer is fetched only when a matching file is opened.
## Frozen standard baseline [#frozen-standard-baseline]
`@file-viewer/preset-standard` includes these package-level groups:
* Word, DOCX, DOC, RTF, and OpenDocument text;
* PDF and OFD;
* modern OpenXML PowerPoint through `@file-viewer/renderer-pptx`;
* Excel, CSV/TSV, OpenDocument Spreadsheet, and DBF;
* archives and email;
* text, code, Markdown, images, audio, and video.
Specialist capabilities such as iWork, DICOM, digital-signature containers, CAD, 3D, EDA, Geo, Typst, drawing, WordPerfect, Hangul, and legacy binary PPT stay explicit. This keeps additions to the global format catalog from silently growing every standard install.
The PPT split is also an install boundary. Modern `.pptx` uses `@file-viewer/renderer-pptx`. Legacy `.ppt` uses `@file-viewer/renderer-ppt` and its separately licensed runtime. The compatibility aggregate `@file-viewer/renderer-presentation` continues to provide both for existing users.
## Existing Full packages do not change [#existing-full-packages-do-not-change]
The eight published `@file-viewer/*-full` packages keep their existing:
* `preset-all` capability matrix;
* public API and default integration behavior;
* runtime asset paths and copy-assets behavior;
* formats that were part of the package when released.
They will not be silently switched to `standard`. Installing one of those packages directly also does not promise that every specialist renderer introduced in a later release will become a new transitive dependency. That rule prevents an unchanged application from accumulating unbounded downloads as the catalog grows.
The CLI's `--profile full` is an explicit convenience contract. It preserves the matching compatibility Full package, then adds the later opt-in capabilities in the installed CLI catalog. The CLI shows package weight and license information before it asks for confirmation.
```bash
npx file-viewer-cli plan --framework vue3 --profile full
npx file-viewer-cli create my-viewer --framework vue3 --profile full --yes
```
The current later opt-ins are DICOM and digital-signature containers. The DICOM renderer covers one local Part 10 file, including multi-frame navigation; it does not provide series assembly, PACS/DICOMweb, MPR, segmentation, diagnostic interpretation, or an embedded OHIF application. The signature renderer performs bounded local inspection of CMS/CAdES, timestamps, ASiC, evidence records, JWS, and public OpenPGP material. It keeps cryptographic results separate from trust, policy, qualified-signer identity, and legal validity; it accepts no private key and never follows remote key URLs automatically.
## Add specialist formats only when needed [#add-specialist-formats-only-when-needed]
Select file extensions or capability ids on top of `standard`:
```bash
npx file-viewer-cli create viewer \
--framework react \
--profile standard \
--formats dwg,typst \
--yes
```
Or evolve a configured project:
```bash
npx file-viewer-cli config add dwg --write
npx file-viewer-cli config add dicom --write
npx file-viewer-cli config add p7m --write
npx file-viewer-cli plan
npx file-viewer-cli install --yes
npx file-viewer-cli verify --json
```
The generated integration module imports only the fixed profile and selected additions. `plan` reports the exact packages, asset owners, heavy capabilities, and license notices. Use its current catalog output instead of copying historical package-size numbers into deployment policy.
## Capability contract [#capability-contract]
Renderer packages can publish `file-viewer.capability.json` through `package.json#fileViewer.capabilityManifest`. The schema records:
* owned formats and renderer ids;
* public-asset renderer ids;
* SPDX license and distribution policy;
* `light`, `standard`, or `heavy` install weight;
* preset/profile membership.
The CLI catalog is generated from those declarations plus `ecosystem/format-catalog.json`. Repository gates reject format drift, unknown asset ids, a heavy capability entering `standard`, or a profile/package dependency mismatch.
## Recommended migration [#recommended-migration]
1. Leave existing Full and `preset-all` applications on their current packages unless there is a product reason to change them.
2. Use `standard` for new common-format applications and add specialist capabilities explicitly.
3. Run `file-viewer plan` before installation and commit `file-viewer.config.json` as the selection record.
4. Deploy only the selected runtime assets, or retain the complete compatibility copy-assets workflow where an existing Full installation requires it.
5. Run `file-viewer doctor` and `file-viewer verify` in CI so package, generated-module, receipt, and asset drift fails before deployment.
See the [complete CLI guide](/guide/cli) for scaffold creation, existing-project detection, asset compatibility, private registries, and offline tgz preparation.
---
# XML validation and transformation (/guide/xml-profiles)
Available in 3.1.2 and later. Ordinary `.xml` files still use the text renderer. Install and explicitly enable profiles when your application needs XSD validation and an XSLT-generated document view.
## Setup [#setup]
Install the optional engines and copy their assets from your installed packages:
```sh
npm install @file-viewer/web @file-viewer/renderer-text xmllint-wasm@5.3.0 xslt-polyfill@1.0.29
npx --no-install file-viewer-xml-assets public/file-viewer/xml
```
Serve the copied runtime files and licenses from your own origin. The copier checks engine versions and writes a SHA-256 manifest; it never downloads packages. Standard text and Full imports do not load these engines.
```ts
import { mountViewer } from '@file-viewer/web'
import { textRenderer } from '@file-viewer/renderer-text'
import { enableFileViewerXmlProfiles } from '@file-viewer/renderer-text/xml-profiles'
const disableProfiles = enableFileViewerXmlProfiles()
mountViewer(document.querySelector('#viewer'), {
url: '/documents/invoice.xml',
filename: 'invoice.xml',
options: {
renderers: [textRenderer],
xml: {
profilesUrl: '/profiles/profiles.json',
runtime: {
xsdWorkerUrl: '/file-viewer/xml/xmllint-browser.mjs',
xsltModuleUrl: '/file-viewer/xml/xslt-wasm.js'
},
onDiagnostic: diagnostic => console.info(diagnostic)
}
}
})
// Call disableProfiles() when the application's registration is no longer needed.
```
The component has **View Source** and **View Rendered** buttons after a successful transformation. Toggling does not fetch or parse the original again. `xml.initialView: 'source'` keeps source visible initially. Diagnostic callbacks are optional and do not determine whether rendering succeeds.
## Profile manifest [#profile-manifest]
```json
{
"profiles": [{
"id": "invoice-v1",
"match": {
"rootNamespace": { "enabled": true, "root": "invoice", "namespace": "urn:example:invoice:v1" },
"xsd": { "enabled": true }
},
"xsd": "./invoice.xsd",
"xslt": "./invoice.xsl"
}]
}
```
Resource paths are relative to the manifest URL. Alternatively, supply `xml.profiles` with `xml.baseUrl`; do not also set `profilesUrl`. Every enabled check must pass, and exactly one profile must match. Zero matches, multiple matches, malformed configuration, failed validation, unavailable assets or a transformation error all leave the original XML visible with diagnostics. XSD-only and root/namespace-only profiles are supported; at least one check must be enabled.
XSD uses libxml2 through `xmllint-wasm`; XSLT 1.0 uses libxslt through `xslt-polyfill` in a Worker. It does not depend on the browser's native `XSLTProcessor`. Use HTML output in the stylesheet. XSD imports/includes, XSLT imports/includes, `document()`, extension instructions, DTDs and external entities are rejected. Flatten schemas and stylesheets into reviewed, self-contained resources before deployment.
## Limits and isolation [#limits-and-isolation]
Resources must be same-origin HTTP(S), without redirects. Runtime URLs are application configuration, never taken from the XML document. The output is sanitized into a sandboxed iframe without scripts or same-origin access; it cannot execute application code or load external resources.
Defaults and hard ceilings are 4 MiB XML, 2 MiB per schema/stylesheet, 8 MiB output, 32 profiles and 16 MiB total fetched resources. `xml.limits` can lower these limits. `timeoutMs` defaults to 15 seconds and is capped at 60 seconds. Workers are terminated on timeout, cancellation and unmount. Each WASM engine has a 64 MiB linear-memory ceiling. Larger or unsupported documents fall back to source; no validation result is fabricated.
CSP must allow same-origin assets, blob Workers and WASM compilation. Keep the runtime JavaScript, WASM and license files together when deploying under a subpath, and update the two explicit URLs accordingly. The Demo includes a valid invoice and an invalid invoice to exercise both the rendered view and fallback.
---
# File Viewer Documentation (/)
File Viewer keeps private documents in the browser and avoids a server-side conversion pipeline. Start with a native component, add only the renderer capabilities you need, and publish every Worker, WASM, font, and vendor asset from your own origin.
## Start with the right path [#start-with-the-right-path]
| Goal | Recommended guide |
| ----------------------------------------- | ----------------------------------------------------- |
| Run the shortest complete example | [Quickstart](/guide/quickstart) |
| Integrate without a framework | [Vanilla JS and Web Component](/guide/quickstart-web) |
| Choose standard, preset, or Full packages | [Ecosystem packages](/guide/ecosystem) |
| Verify exact file coverage | [Supported formats](/guide/formats) |
| Keep every runtime asset offline | [Distribution and self-hosting](/guide/distribution) |
## What the documentation covers [#what-the-documentation-covers]
* Browser-native integration for Vanilla JS, Web Component, Vue, React, Svelte, and jQuery.
* Standard packages, modular renderers, product-shaped presets, and complete Full packages.
* PDF, Office, CAD, archives, email, media, drawing, code, 3D, and engineering formats.
* Shadow DOM style isolation, theme tokens, toolbar customization, print, export, and search.
* Docker, CDN/IIFE, private deployment, offline assets, and release verification.
## Verify before you ship [#verify-before-you-ship]
The documentation is generated as semantic static HTML. Every canonical page has its own title, description, Open Graph and X metadata, structured data, raw Markdown endpoint, and English/Chinese alternate. Search runs locally in the browser; the published site does not require a documentation server.
---
# 更新日志 (/zh/changelog)
这份日志记录的是当前仓库主线中,对外最值得说明的能力演进。
## `v3.0.3` Word 修订、浏览器集成与移动端 PDF 修复 - 2026-09-09 [#v303-word-修订浏览器集成与移动端-pdf-修复---2026-09-09]
* MapLibre 6.4.1 修复地图署名 HTML 连续危险属性的清洗绕过;离线 Worker 内置,地图销毁重建后仍能加载。同步更新 js-yaml、sharp 和 Vitest 安全版本,以实际所需 polyfill 替代未使用的 Browserify 工具链。
* 标准预览固定使用 JSZip 3.10.2,修复跨 JavaScript 上下文的二进制类型识别,并保持构建与冷安装版本一致。
* core 与各渲染器统一固定 DOMPurify 3.4.15,纳入 XML 消毒安全加固并避免冷安装重复引入多个版本,体积预算不变。
* Demo 顶部按钮悬停不再改变文档顶部留白或 CAD 导出尺寸。
* 二进制 DOC 保留插入/删除修订、段落和软换行标记;Word 可直接切换全部修订、最终稿和原稿,无需重选文件。修正 DOC 行距单位和字体槽位,按提供的销售合同验证正文和表格,不凭空添加修订线。
* 表格列宽拖拽后随缩放变化并按 sheet 恢复;不可见区域搜索覆盖真实 XLS、远列和合并单元格。CFB 只跳过未使用的损坏 MiniFAT 链,必需工作簿数据仍严格校验。
* 修复 iPhone Safari PDF 翻页及搜索键盘收起后的导航恢复;取消 PDF 初始化不再产生未处理的 Worker 终止异常。
* 修正 Vue CLI/Webpack、Angular 和嵌套 Vite 的浏览器入口及 PPTX Worker 资产定位,保留显式路径优先级。新增 RequireJS AMD 入口,不修改宿主 `define`,懒加载资源仍由本地提供。
* HTML 提供静态预览和原始源码切换,不执行脚本或外部请求。OFD 正确处理声明的资源路径和命名空间,必需页面错误不再挂起。CAD 修复 DXF LINE、DWF/DWFx 对比度,PNG/JPEG 当前视图下载遵守权限、钩子和水印。
* PDF 补丁携带可验证的来源哈希;CHM、Adobe 和 Illustrator 安全修复同步至分发 Worker。独立组件源码构建补齐输入,发布按依赖层批量推进,并按完整性校验安全续跑。
87 个主线包对齐 `3.0.3`,`msdoc-viewer` 升至 `0.2.6`。上游引擎为 DOCX `0.3.31`、styled-exceljs `0.21.6`、CAD `0.8.2` 和 DWF `0.6.7`。Vue 2.6/2.7 和既有 Full 能力不变,pako 3 继续暂缓。本 patch 同时包含 HTML 视图、AMD 入口和 CAD 图片下载等新增能力。
\#227 私有 XLS、#236 删除修订截图对应的文件及历史 #57 OFD 仍缺少原件;构造样本和已提供合同不能替代对应原件的验收。
## `v3.0.2` 修正版:表格搜索、DOCX 形状与 CAD 单色输出 — 2026-09-06 [#v302-修正版表格搜索docx-形状与-cad-单色输出--2026-09-06]
本版取代 3.0.1。由于 npm 已有下游依赖,已发布的 3.0.1 不能被完整撤回;3.0.2 发布后会将仍可变更的 3.0.1 包标记为 deprecated。
### 问题修复与回归 [#问题修复与回归]
* 修复 #247:表格搜索不再受当前虚拟渲染窗口限制,会搜索已解析工作簿中的真实单元格,加载目标窗口并跳转到匹配位置;真实 `apps/viewer-demo/public/example/excel.xls` 已通过浏览器回归。
* 通过升级 `@file-viewer/docx` 到 `0.3.29` 修复 #250 的页面相对定位浮动 shape 问题;报告者的 `test.docx` 已在本地浏览器验证。
* 完成 #213/#245:CAD 单色策略从 DWF、CAD renderer 延续到 HTML/Print 输出,不修改原始数据;真实 DWF 回归通过。
* 重新执行 #242 的 Vite/PDF 中文字体资产边界、#232 的 `postal-mime@3.0.0` EML 正确性以及 Vue 2.6 CLI 3 Office 样例,Vue 2 仍在发布门禁内。
### 可采纳依赖 [#可采纳依赖]
* 采用安全的 Dependabot 子集:`pako@2.2.0`、`proj4@2.22.0`、`vite-plugin-dts@5.1.0`、`cnfast@0.2.0` 和 `prettier@3.9.6`。
* pako 3 继续暂缓,因为 DICOM `Inflate` 的错误/消息语义由 `packages/renderers/dicom/src/inspect.ts` 使用;Next 16.3.4 因引入 `sharp-libvips` 未通过 LGPL 许可证门禁。
### 发布组成 [#发布组成]
同一提交冻结 88 个 npm 目标:87 个主线包为 `3.0.2`,历史 `msdoc-viewer` 别名保持 `0.2.5`;外部引擎为 `@file-viewer/docx@0.3.29` 和 `styled-exceljs@0.21.4`。
## `v3.0.1` 宿主框架 peer 依赖、PDF 中文兜底字体与 EML 头部修正 — 2026-09-03 [#v301-宿主框架-peer-依赖pdf-中文兜底字体与-eml-头部修正--2026-09-03]
### 可读文本预览 [#可读文本预览]
* 新增可选的可读文本预览(#235):普通与有界虚拟文本按逻辑行换行;结构化文本按格式懒加载 Prettier parser,以徽标和切换按钮区分格式化显示副本与原始源码。格式化阈值独立于大文本渲染,下载始终保留原始字节。
### CLI 可靠性与交互 [#cli-可靠性与交互]
* 新建项目的交互式格式选择改为预先列出 renderer/格式族并显示勾选状态;当前 profile 已包含的能力保持启用,额外能力支持编号、范围、全选和清空,不再要求手写扩展名。
* Vite 8 脚手架声明并在 `dev`/`build` 前校验 Node `^20.19.0 || >=22.12.0`,旧运行时会获得明确迁移提示;Web Component 事件从元素所属 document realm 创建,并为缺失全局 `CustomEvent` 的 DOM 环境保留兼容回退。
### 新增格式渲染器 [#新增格式渲染器]
* 新增 `@file-viewer/renderer-chm`:CHM 帮助文档在浏览器内离线解析,Rust/WASM 解包配合沙箱阅读器还原目录、正文与图片,不上传任何文件内容。
* 新增 `@file-viewer/renderer-design`:Adobe 设计文件离线预览,覆盖 PSD/PSB 图层、Illustrator 原生 PGF 与 PDF 兼容表面、IDML/ICML/INX、INDD/XD、现代 XFL 动画与色板、画笔等资源文件;作为显式按需包交付,Worker、WASM 与字体全部可自托管。
### PDF [#pdf]
* 修复 #242 报告的 3.0 打包失败(Vite 8 + pnpm 11 + Node 22):`@file-viewer/vite-plugin` 从 2.4 起就把 PDF 资产列为必需,2.4 之所以能通过,是因为 `@fontsource-variable/noto-sans-sc` 当时是 `@file-viewer/renderer-pdf` 的运行时依赖;3.0.0 把该字体降级为 devDependency,安装后的应用解析不到任何字体来源,必需资产缺失直接中断 `vite build`,因此回退 2.4 看起来像修复。3.0.1 把字体来源上移到启用 PDF renderer 的 preset:`preset-office`、`preset-all` 直接声明字体包,`preset-standard` 由 `@file-viewer/assets-standard` 提供;`@file-viewer/renderer-pdf@3.0.1` 的发布包内不再携带任何字体副本(tarball 已核对),而在确实没有字体来源时该资产改为可选,构建输出警告而不是失败,PDF 继续依赖文档内嵌字体。该资产归属与可选性由 #242 门禁与 profile 门禁持续校验。
### 邮件 [#邮件]
* EML 解析基线升级到 postal-mime `3.0.0`(#232):未声明字符集的部件按邮件头编码正确回退,折叠的 RFC 5322 头部完整展开,重复头部按首个生效,`to`/`cc`/`bcc` 保持原始顺序。
### 生态组件安装 [#生态组件安装]
* `@file-viewer/vue3` 不再把宿主框架 `vue` 作为运行时依赖安装,改为 `peerDependencies: ">=3.3 <4"`,与 Vue 2.6/2.7、React、Svelte、jQuery 组件保持一致;构建期图标库同步移入 devDependencies,直接运行时依赖只剩 `@file-viewer/core`。这修复了应用锁定的 Vue 版本与组件自带版本不一致时安装出两份 Vue 实例、组件挂载抛 `Cannot read properties of null (reading 'refs')` 并留下空白页面的问题。
* 新增宿主运行时契约门禁:生态组件的可安装依赖只允许 File Viewer 自身包,宿主框架必须且只能声明为 peer,且三条 Vue 版本线互不重叠;冷安装校验在安装完成后立即比对宿主框架的解析路径,出现重复副本时直接失败并给出可读原因。
* `msdoc-viewer` 历史兼容别名升到 `0.2.5` 以跟随 3.0.1 的 `@file-viewer/doc`:该别名按解析到的 Word renderer 版本发布,同一冻结版本无法二次发布。本次发布冻结 88 个 npm 目标:87 个主线包为 `3.0.1`,`msdoc-viewer` 别名为 `0.2.5`。
### 依赖安全 [#依赖安全]
* XMind 解析路径不再解析 `@xmldom/xmldom` 0.9.10:该版本带有 6 项安全公告,且均可由预览不可信文件时的 `DOMParser.parseFromString` 触发;依赖覆盖将整张依赖图锁定到 0.9.12,开源边界校验会持续确认该覆盖确实生效(#246)。
## `v3.0.0` 模块化 CLI、专业格式按需安装与安全门禁 — 2026-08-27 [#v300-模块化-cli专业格式按需安装与安全门禁--2026-08-27]
* 新增 `@file-viewer/cli`、`file-viewer-cli` 和 `create-file-viewer`,既可创建新项目,也可在已有 `package.json` 工程中检测框架与构建工具后安装;支持选择框架版本、格式、preset、资源、npm/pnpm/Yarn/Bun、不含凭据的私有 registry 与完整性校验的离线 tgz。
* `standard` 成为常用格式的推荐方案,但不改变八个已发布 Full 包。`*-full` 继续交付原 `preset-all` 格式矩阵、API 和同版本离线资源;CLI 显式选择 `full` 时才在此基础上加入后续专业能力,并提前展示体积、运行时和许可边界。
* DICOM 和数字签名容器不进入未改动的 Full 依赖。可选 DICOM renderer 支持有界的本地单文件、单帧/多帧预览,覆盖未压缩、JPEG Lossless、JPEG-LS 和 JPEG 2000 Lossless;不声称诊断、PACS/DICOMweb 或多文件序列能力(#210)。
* 可选签名与证据容器 renderer 有界检查 CMS/CAdES、RFC 3161/5544、ASiC-S/E、RFC 4998、JWS 和公开 OpenPGP 材料。它使用许可宽松的 rPGP Worker/WASM,不包含 LGPL 源码,并分开报告解析、摘要/签名检查、信任和法律效力(#206)。
* 修复 #200 报告者提供的五页 PPTX 布局样例,覆盖 DrawingML 表格边界/内边距、SmartArt 水平文字、复杂形状和 PPTX Worker,并通过 Chromium、Firefox 与 WebKit。
* 还原 #211 报告样例的 Excel 表格主题、表头和交替行样式,列宽拖拽在切换 sheet 后继续保留;同时增加 #203 异常合并信息和稳定 Office 列宽回归。
* React、React Full、React Legacy 和 React Legacy Full 支持邮件附件嵌套预览,并覆盖恶意附件名、缓冲区替换、卸载、Worker 和 Object URL 清理(#212)。
* 重新执行 #178 的 Office 365/WPS 单元格内嵌图、浮动图、TIFF、Worker 传输、双击大图和可选列宽拖拽回归。
* DOC、RTF、PPTX、Markdown、Mermaid、Drawing、PlantUML 和 Typst 的文档内容到 HTML/DOM 边界统一加固;外链默认阻断,CSP 与 Trusted Types 在 Chromium、Firefox 和 WebKit 通过。
* 冻结 84 个 npm 目标:83 个主线包使用 `3.0.0`,历史兼容包 `msdoc-viewer` 使用 `0.2.4`;外部自研引擎固定为 `@file-viewer/docx@0.3.28` 和 `styled-exceljs@0.21.4`。
* 正式发布只提升冻结提交在构建、测试、安全门禁、冷安装、浏览器矩阵和 `npm publish --dry-run` 中通过的原始 tarball;发布阶段不重建、不临时增加稳定版本。
## `v2.4.0` 统一版本与冻结候选发布 — 2026-08-25 [#v240-统一版本与冻结候选发布--2026-08-25]
* 根版本、GitHub Release 与 56 个常规 npm 包统一为 `2.4.0`;历史兼容包 `msdoc-viewer` 使用独立的 `0.2.3` 版本。
* Spreadsheet 与 iWork 渲染链升级到 `styled-exceljs@0.21.3`,覆盖无原型工作表映射、有界 XML/标签处理,以及文档生成 HTML、CSS、链接、图片和属性的安全序列化。
* 重新验证 #178 的 Office 365/WPS 单元格内嵌图、浮动图、TIFF、Worker 传输、双击大图和可选列宽拖拽;版本统一没有移除 Excel 列宽调整能力。
* 稳定发布只提升已通过完整构建、冷安装与 npm dry-run 的原始 tarball。预演回执固定源提交、包集合、字节大小和 SHA-512,正式发布命令不再重新构建。
## `v2.3.2` 多页 TIFF 与 Vite 8 分块兼容 — 2026-08-24 [#v232-多页-tiff-与-vite-8-分块兼容--2026-08-24]
* TIFF 路径按需加载 MIT 许可的 UTIF.js,支持 CCITT Group 4、多页纵向展示、整组缩放/旋转/适宽、页码状态,以及双击或键盘大图查看(#208)。
* 对编码大小、页数、单页尺寸、单页像素和累计解码像素设置硬限制;逐页转换会释放 RGBA 和 Object URL,普通 PNG/JPEG/WEBP 路径不加载 TIFF 解码器。
* Vite 8 改用 Rolldown `codeSplitting.groups`,Vite 5—7 继续使用 Rollup `manualChunks`;用户分组、优先级、输出数组和 `codeSplitting:false` 保持不变(#209)。
* 使用 #178 原始 Office 365/WPS 内嵌图片工作簿再次验证主线程、Worker、TIFF drawing 与大图查看路径,Excel 列宽拖拽能力没有被移除。
* 实际发布版本为 `@file-viewer/renderer-image@2.3.1`、`@file-viewer/vite-plugin@2.3.3`、`@file-viewer/preset-lite@2.3.1`,以及统一的 All/Full/copy-assets 2.3.6 补丁线;本版继续包含 v2.3.1 的全部安全修复。
## `v2.3.1` 旧版 DOC 渲染安全补丁 — 2026-08-24 [#v231-旧版-doc-渲染安全补丁--2026-08-24]
* 旧版 DOC 直接 HTML API 会对文档提供的字体名和生成属性正确编码,避免文档内容突破样式或 HTML 属性边界。
* DOC 外部链接改为默认阻断;内部书签保持可用,显式允许时也只接受 HTTP(S)、邮件、电话和安全相对地址。
* 标准挂载路径在文档标记进入 DOM 前使用 DOMPurify 3.4.13 再次净化,renderer CSS 通过 `textContent` 注入。
* 净化器只进入 DOC 懒加载路径;压缩后为 10,923 字节,并由 15 KiB 发布门禁约束后续增长。
* 修复版本为 `@file-viewer/doc@2.3.1`、`msdoc-viewer@0.2.2`、`@file-viewer/renderer-word@2.3.2`,以及 Office/Full/copy-assets 的 2.3.4 补丁线。
## `v2.3.0` Office/iWork 扩展与真实文件修复 — 2026-08-20 [#v230-officeiwork-扩展与真实文件修复--2026-08-20]
* 将 Pages、Numbers、Keynote、WordPerfect、Hangul、DBF、FB2、XLA/XLAM 与 POT 纳入稳定格式矩阵;当前唯一目录包含 221 个扩展名和 32 条预览链路。
* 完整发布 #174、#178、#179、#195、#198、#201—#204 对应修复;#200 因缺少原始 PPTX 继续保留。
* 修复 Excel Office 365/WPS 单元格内嵌图片、工作簿绘图、文件原始列宽、Shadow DOM 列宽拖拽,并支持双击图片放大;用户后续提供的 TIFF drawing 会按需在浏览器内解码,主线程、Worker 与大图预览使用同一路径。
* DOCX 引擎升级到 `@file-viewer/docx@0.3.27`,修复复杂框架、分节、定位页面和锚定内容;Worker 缓存参数同步到实际运行时版本。
* 加固 PPTX Worker 输出、Markdown 渲染、压缩包文件名解码、包依赖与离线 Worker/WASM 交付。
* PPTX 按需构建不再携带仅供二进制 PPT 使用的 CJK 字体和原生 WASM;Vite 5–8 会按 `package.json#exports` 正确解析 `renderer-presentation/pptx` 子路径(#205)。
* 源码和 GitHub Release 版本为 v2.3.0;npm 不可覆盖的更正包按实际版本使用 `@file-viewer/renderer-spreadsheet@2.3.2`、`@file-viewer/renderer-iwork@2.3.1`、`@file-viewer/renderer-word@2.3.1`、`@file-viewer/renderer-presentation@2.3.1`、`@file-viewer/vite-plugin@2.3.2`,以及 Office/Full/copy-assets 的 2.3.3 补丁线。TIFF drawing 元数据由 `styled-exceljs@0.21.2` 提供。
## `v2.2.9` PPTX 与 Markdown 渲染安全补丁 — 2026-08-17 [#v229-pptx-与-markdown-渲染安全补丁--2026-08-17]
npm 包于 2026-08-13 发布;GitHub Release 于 2026-08-17 完成最终归档。
* PPTX Worker 产生的 HTML、SVG、内联样式与全局 CSS 在进入预览 DOM 前统一经过严格净化;外部媒体/矢量资源 URL、危险链接协议、事件属性、脚本、全局选择器和不安全 CSS 声明会被移除。
* PPTX XML 中的超链接 tooltip、形状属性、颜色与字体字段获得入口级校验;正常本地片段、base64 图片、blob 媒体和生成类规则保持可用。
* Markdown 的 Marked 输出改为先经 DOMPurify 再插入文档,新窗口链接自动使用 `noopener noreferrer`;DOMPurify 3.4.13 与 Mermaid 11.16.1 同步进入直接依赖。
* 自托管 Chromium 门禁同时覆盖恶意 Markdown、伪造 PPTX Worker 与真实恶意 PPTX Worker,验证普通/虚拟化两条渲染路径均不执行脚本、不污染全局样式且不发起攻击者控制的请求。
* 54 个 npm 目标、208 个扩展名和 25 条预览链路保持不变。
## `v2.2.8` 大表格、OFD 首屏与二进制 PPT 观感修复 — 2026-08-11 [#v228-大表格ofd-首屏与二进制-ppt-观感修复--2026-08-11]
* Spreadsheet 自动列宽只对有界行集取样,避免每次适配时全量遍历大工作表。76 MB、259,702 行真实 XLSX 在修复后完成解析、布局和浏览器渲染(GitHub #173)。#193 的原始样例为 38,732,752 字节、100,545 行 × 20 列,worksheet 与 sharedStrings 解压后合计约 108 MB;冷首屏 4.194 秒,末行虚拟滚动、100,545 / 100,545 行缓存和无控制台错误均完成验证。
* OFD 页面在初始布局完成前禁用 transform transition,第一帧稳定后再恢复缩放动画;减少动效偏好仍被完整尊重(GitHub #194)。
* `@file-viewer/ppt@0.3.3` 保留开源二进制 PPT 强制水印,但从重复斜向覆盖改为单个右下角标记,在批准的空白帧 fixture 中覆盖像素从 9,145 减少到 644。水印仍由 native 最终帧合成且无关闭通道。
* PPT 水印的尺寸按 1x/2x/3x 设备像素比整数增长,避免 Retina 与其他高分屏上的半像素边缘;三种 DPR 均通过真实浏览器渲染和像素区域证明。
* PDF 缩放锚点(GitHub #191)和 HTML-in-WordDocument 旧版 DOC 容错(GitHub #192)随本版完成 GitHub Release、组件仓、Demo、文档、官网、Docker 与 npm 的统一分发。
* 官网可交互预览的 pointer ownership、悬停切换与移动端入口完成回归;发布工具对 npm 短暂超时、未确定 registry 状态和中断后续传改为显式保护。
* 能力矩阵保持 54 个 npm 目标、208 个扩展名和 25 条预览链路。
## `v2.2.7` PDF 缩放定位与旧版 Word 容错补丁 — 2026-08-11 [#v227-pdf-缩放定位与旧版-word-容错补丁--2026-08-11]
* PDF 工具栏的放大、缩小和 API 缩放会先记录当前页与页内可视比例,再在 PDF.js 完成重新布局后恢复同一锚点;连续点击也不会短暂切换活动页(GitHub #191)。
* 部分扩展名为 `.doc` 的文件实际是 CFB 容器,`WordDocument` 流中保存 GB18030/UTF-8 HTML 且没有 `0Table`/`1Table`。解析器现在会在 FIB 之前识别这种明确格式,过滤脚本等不安全内容并转换为正常 AST,不再报 `Missing table stream`(GitHub #192)。
* `flyfish-dev/docjs` 所属仓库同步当前 legacy DOC 引擎,并独立通过表格、WPS、OfficeArt 图片、文本框 story 和 HTML-in-WordDocument 样例回归。
* 官网的文件预览 Hero 增加可交互卡片、悬停焦点和主题切换,同时收紧桌面与移动端的信息层级。
* 54 个 npm 目标、208 个扩展名和 25 条预览链路保持不变。
## `v2.2.6` 大文件、分页导航与 Office 交互稳定性补丁 — 2026-08-10 [#v226-大文件分页导航与-office-交互稳定性补丁--2026-08-10]
* Spreadsheet 会在解析阶段按真实单元格收紧异常 worksheet dimensions,避免格式化到整张工作表的文件造成巨量空行/列;图表发现改为读取 worksheet relationship,不再重复把大型 worksheet XML 解压为字符串(GitHub #173/#175)。
* Vue 3 与其他窄宿主首次打开 Spreadsheet 时按实际可视宽度计算 fit,桌面宽容器仍保持 100% 初始比例(GitHub #172)。
* OFD renderer 新增上一页、下一页、当前页/总页数、手动滚动同步、首尾禁用状态与键盘导航;resize 后保留活动页,打印时隐藏导航工具栏(GitHub #177)。
* Word renderer 会在正确的 DOCX renderer 边界拦截内部关系和外部 URL 的默认导航,同时保留链接文字;旧版 DOC 的文本框 story 也会从底层结构恢复,不再只显示占位字形(GitHub #171/#183)。
* PDF 在目录跳转、翻页、旋转和缩放状态回放后保留当前页与可视锚点,页码和页面不再突然向上跳动(GitHub #184)。
* `@file-viewer/pptx` 修复 connector 起终点、翻转和零尺寸 viewport 的几何计算;File Viewer 仅同步正式引擎产物,并通过专用几何 harness 与完整浏览器回归(GitHub #176)。
* 官网重新整理导航、支持矩阵、商业版和移动端入口,补齐 canonical redirect、IndexNow 和机器可读引用元数据;Crawler URL 仍不会进入离线运行时资产错误扫描。
* 发布前后回归覆盖冷安装、全 workspace 类型检查、根测试、全量构建、离线与 renderer 资产、28 格式矩阵、PDF/DOCX/XLSX/PPTX Demo,以及八类标准组件浏览器入口。
* 54 个 npm 目标、208 个扩展名和 25 条预览链路保持不变。
## `v2.2.5` 文档审阅、打印与 Office 图形渲染补丁 — 2026-08-01 [#v225-文档审阅打印与-office-图形渲染补丁--2026-08-01]
* 文档比对页使用成熟的 `jsdiff` 对两侧提取文字逐行对齐,并在替换行内标记具体字符;提供新增、删除、修改、未变化计数、上下差异导航和“只看差异”。DOCX、Markdown、代码和纯文本是稳定路径;PDF 仅在文本层覆盖完整页面时展示,扫描 PDF 暂不内置 OCR(GitHub #145)。
* 打印蒙版支持上传本地印章图片,并按实际文档页拖动、缩放、删除和导出到打印 HTML;已有矩形蒙版与多 renderer 页索引保持兼容(GitHub #157)。
* 文件加载前可以通过统一守卫拒绝或确认来源;PDF 搜索/定位可聚焦真实可见区域,并修复边界框、同步滚动和旋转状态回放(GitHub #151/#154)。
* Geo renderer 增加天地图矢量、影像与地形底图预设;默认不开启公网请求,业务仍需显式提供可用配置(GitHub #153)。
* DOCX 页面背景与浮动覆盖层恢复正确层级;PPTX 清理残留图表节点,并修复组合形状中的梯形、平行四边形等几何映射和层级关系。
* 图片预览新增旋转并优化 Lightbox 缩放/拖动;首页部署修复旧 HTML 缓存被当作 JavaScript 模块返回造成的严格 MIME 报错。
* Vue 2.6 + Vue CLI 3 / webpack 4 客户样例、Docker 发布上下文、组件构建和公开仓边界均完成完整回归。
* 54 个 npm 目标、208 个扩展名和 25 条预览链路保持不变。
## `v2.2.4` DOCX/CAD 运行时与沉浸式预览稳定性补丁 — 2026-07-28 [#v224-docxcad-运行时与沉浸式预览稳定性补丁--2026-07-28]
* Vue 2.6 + Vue CLI 3 / webpack 4 客户样例改为真实 `preset-office` 加图片、视频、CAD、3D 的显式补充装配;PDF.js legacy 模块会整体隔离内部 `modules`、`module_cache`、`exports`、`require` 四个 webpack runtime 标识,避免首次 PDF 初始化污染宿主导出、重选文件后从 `undefined` 读取 `createFileViewerTranslator`。DOCX ESM alias、同一本地 PDF 连续选择、图片和视频真实浏览器回归同步固化。
* Word 链路升级到 `@file-viewer/docx@0.3.26`。日文模板的东亚字体回退、行高和 VML 文本框不再导致字符重叠(GitHub #155);Apache POI 输出的兼容 OOXML `w:hMerge restart/continue` 会规范化为真实列跨度,异常孤立 continuation 仍保持可读(GitHub #160);多分节中文简历中的浮动形状、定位尺寸和页内内容流恢复原有关系,目录不再被挤压错位(GitHub #161)。主线程与离线 Worker 使用同一版本,并用 `0.3.26` 资源查询参数避免旧 Worker 缓存残留。
* CAD 链路使用 npm `latest` 的 `@flyfish-dev/cad-viewer@0.8.0`。底层引擎新增 BOM 提取与表格安全的 CSV/JSON 导出接口,收紧 DWG/DXF 元数据边界,并把 LibreDWG WASM 升级到 0.7.9;复杂线型 STYLE 引用为空时,合法图纸不再因解析异常而无法加载。
* Word 链路升级到 `@file-viewer/docx@0.3.23`。东亚语言和主题字体按文档语言脚本解析并保留可靠的系统字体回退,悬挂制表位、目录缩进和 HTML 样式属性的渲染更接近 Word;Worker 与主线程继续使用同一解析行为。
* Archive renderer 在压缩包内选中 Shapefile `.shp` 时,会按同目录和同 basename 收集 `.dbf`、`.shx`、`.prj`、`.cpg` sidecar,生成有界的临时 ZIP 后交给既有 Geo renderer;多数据集压缩包不会串用属性或投影文件,普通压缩包预览路径保持不变(GitHub #148/#149)。
* Word 链路升级到 `@file-viewer/docx@0.3.22`。缺失或部分缺失 `sectPr` / `pgSz` / `pgMar` 的 DOCX 在共享解析层获得 A4 页面和 1 英寸正文边距兜底,主线程与 Worker 行为一致;显式自定义尺寸、横向布局、零边距和附件保持不变(GitHub #150)。
* OFD 渐进渲染进入最终 ready 状态时不再重新隐藏已经可见的内容,消除大文件预览的二次闪烁;89 页样例会记录可见性 mutation 并确认不存在 ready 后回退(GitHub #163)。
* STEP/STP 重复预览时,Three.js Canvas backing buffer 会按当前 CSS 尺寸与设备像素比持续校正;即使外部流程把 backing buffer 降到 1×,下一渲染帧也会恢复清晰分辨率(GitHub #164)。
* Demo 首屏只按收起后的文件胶囊预留文档起始位置;开始滚动后文档可以自然进入胶囊后方,继续保持全视口沉浸滚动和透明滚动条。
* 日语界面完成核心消息、工具栏和样例入口覆盖;54 个 npm 目标、208 个扩展名和 25 条预览链路保持不变。
## `v2.2.3` 工具栏隔离与演示文稿运行时兼容补丁 — 2026-07-21 [#v223-工具栏隔离与演示文稿运行时兼容补丁--2026-07-21]
* Web、Vue 3、Vue 2.7、Vue 2.6、React、React Legacy、Svelte 与 jQuery 共用 Core 浏览器控制器。标准组件默认在 Shadow DOM 中渲染,业务全局 CSS 不再覆盖工具栏;需要参与宿主样式系统时仍可显式设置 `styleIsolation: 'none'`。
* 修复 Shadow/Light 模式在同一宿主重挂时的边界残留,并保护业务自行创建的 ShadowRoot:File Viewer 只管理自己的挂载节点,销毁不会清空业务内容。
* Vue 3 的组件样式和 renderer 样式进入真实 ShadowRoot;Vue 2.6 的事件、状态回调、命令与视图状态 API 和现代组件保持一致。
* PPTX Worker 兼容 Angular 22 application builder 的 `.angular/cache`、Vite 依赖优化和 `baseHref` 路径。
* 二进制 PPT 升级到 `@file-viewer/ppt@0.3.2`。自包含 Worker 修复普通 Vite 生产构建中的相邻模块 404;强制 Worker 模式已在全新临时应用中渲染 25 页真实 PPT,并确认 Worker、WASM 与字体请求全部返回 200。
* 54 个 npm 目标、208 个扩展名和 25 条预览链路保持不变;组件浏览器矩阵与主 Demo 的 136 个样例均完成真实渲染回归。
## `v2.2.2` EPUB 安全依赖与 Docker 响应头补丁 — 2026-07-17 [#v222-epub-安全依赖与-docker-响应头补丁--2026-07-17]
* EPUB renderer 与缩略图包改为按需加载随包交付的本地引擎;构建固定组合 `epubjs@0.3.93` 与 `@xmldom/xmldom@0.9.10`,npm 用户的生产依赖树不再安装旧 XML DOM 包。
* 每次构建都会生成引擎 SHA-256、版本 manifest 和完整第三方 NOTICE;发布门禁会对两个 tarball 做全新官方 registry 安装与 `npm audit --omit=dev`,并验证不存在裸 `epubjs` import 或外部运行时依赖。
* Nginx 中带独立 `Cache-Control` 的 location 显式保留 `X-Content-Type-Options: nosniff` 与 `Referrer-Policy`,避免 location 级 `add_header` 关闭 server 级继承;`.mjs` 保持 `application/javascript`。
* 54 个 npm 目标、208 个扩展名和 25 条预览链路不变;2.2.1 的 PDF 下载、DOCX 锚点和自托管模块修复全部保留。
## `v2.2.1` 上传下载、DOCX 锚点与自托管运行时补丁 — 2026-07-17 [#v221-上传下载docx-锚点与自托管运行时补丁--2026-07-17]
* 修复上传 PDF 完成渲染后下载为 0 字节(GitHub #139)。PDF.js 转移并分离输入 `ArrayBuffer` 后,Core 会使用仍然完整的原始 `File`;流式 URL 和合法空文件保持原有行为。
* Word 链路升级到 `@file-viewer/docx@0.3.21`:WPS/WPG/图片不再重复应用根锚点偏移,嵌套组变换和组内图片正确组合,同段落内的页面/段落锚点也会在真实布局后同步(GitHub #133);缺失页眉或页脚 root 的可选结构在引擎层直接跳过(GitHub #130)。
* Docker/Nginx 为 `.mjs` 返回正确的 JavaScript MIME,`nosniff` 下 PDF.js Worker、PPT 和其他 ESM 资产可以正常动态导入。
* CAD 运行时资源构建支持跨文件系统 `EXDEV`,暂存、复制、交换、回滚和部分清理失败均有确定行为;Docker 上下文和依赖缓存同步优化。
* 54 个 npm 目标、208 个扩展名和 25 条预览链路保持不变;PDF 上传下载、OFD→PDF、PPT、PPTX、复杂锚定 DOCX 和自托管容器均完成真实浏览器回归。#133 附件页面不再溢出,关键区块相对参考 PDF 的横向误差小于 0.4 pt、纵向误差约 2–3 pt。
## `v2.2.0` 产品化 Demo、路径兼容与集中缺陷修复 — 2026-07-17 [#v220-产品化-demo路径兼容与集中缺陷修复--2026-07-17]
* 主 Demo 重新设计为产品化预览工作台:桌面端使用紧凑导航轨、文件来源浮层、顶部文档操作和底部缩放 dock;平板与移动端自动收起非核心操作,暗色模式继续保留独立白色文档纸张。
* 显式 `?url=` 文件入口在首帧前进入沉浸模式,隐藏 Demo 品牌、样例、历史与外层状态,只保留预览器工具栏;桌面与移动端均为满视口文档容器滚动,不产生页面级滚动条。
* `@flyfish-dev/cad-viewer` 升级至 `0.7.0`。DWG Worker、DWF WASM、LibreDWG JS/WASM 四个运行时文件全部作为必需资产发布;复制过程先暂存并校验,再原子交换,失败会回滚,同时保留业务自定义 SHX 文件。
* STEP/STP、IGES/IGS 和 BREP 已通过本地 OCCT Worker/WASM 直接生成 Three.js 网格;装配层级、面颜色、适配、统一缩放、暗色场景、主线程回退以及子路径离线资源都进入真实浏览器回归。IFC 和 3DM 仍只提供准确的能力提示。
* Core 新增统一运行时资源基址 API,Vite 插件把 Full、preset 和独立 renderer 的 `copyAssets.baseDir` 同步到运行时。Angular 深层路由、相对 Vite base、SSR、Windows 分隔符、空格、中文目录,以及路径中包含 `assets` / `static` / `js` 的部署均有确定性回归。
* CSV/TSV 文本解析优先识别 UTF-8 BOM 和严格 UTF-8,无效 UTF-8 自动使用 GB18030(兼容 GBK);`options.spreadsheet.textEncoding` 可显式指定编码,二进制 XLS/XLSX 不进入文本解码路径(GitHub #124)。
* `options.text.lineNumbers` 为普通代码/文本提供可配置行号;行号不会污染复制、全文搜索或屏幕阅读器输出,大文件虚拟滚动和移动端宽度保持稳定(GitHub #125)。
* Markdown 不再被普通文本的 512 KiB 默认阈值自动切成源码视图;默认始终保持 `marked` 排版阅读面,只有显式设置 `options.text.markdownVirtualizeAboveBytes` 才会在超限后进入有界源码模式(GitHub #136)。
* `options.text.toolbar` 默认保持历史元信息栏;显式传 `false` 可隐藏代码、文本和超大 Markdown 源码视图顶部的类型、索引状态与行数,不会误伤 Viewer 全局工具栏(GitHub #137)。
* PPTX 样式会注入真正承载内容的 ShadowRoot,默认 Worker URL 统一从运行时资源基址解析;Web Full IIFE 和 Angular 子路径不再请求站点根 `/worker/pptx.worker.js`(GitHub #127/#129)。
* PDF.js 的 `:root` 变量同时作用于当前 `.pdf-shell`,容器高度由本地 ResizeObserver 维护;全宽 flex grow + `overflow-auto` 宿主在初始 fit、缩小和 forced-colors 下保持居中(GitHub #128)。
* 宿主应用预载 PDF.js 3.x 时,File Viewer 不再让 PDF.js 5.4 复用不兼容的全局 fake-worker handler;本包只在自己的 PDFWorker 初始化期间临时接管 handler,随后完整恢复宿主 namespace(GitHub #134)。
* 静态 PDF Worker 会在实例化前校验官方版本标记;若部署目录残留的 Worker 与当前 PDF.js API 不一致,会自动切换到随包交付的同版本 handler,避免 `API version does not match the Worker version`(GitHub #138)。
* DOCX 渲染器识别缺失页眉/页脚 root 的特定异常,只对该可选结构禁用 headers/footers 并重试正文,其他异常仍按原路径抛出(GitHub #130)。
* Word renderer 会先按文件签名区分 OOXML ZIP 与 CFB:扩展名误写为 `.doc` 的有效 DOCX 不再进入二进制解析器,真实 `.doc` 路径保持不变(GitHub #131)。
* 非 Full 的 `preset-office` 资产复制补齐 `vendor/xlsx/sheet.worker.js`;Vite 子路径、npm/pnpm 冷安装、生产构建和来源版本都加入回归(GitHub #135)。
* PowerPoint 97–2003 二进制 `.ppt` 使用 `@file-viewer/ppt@0.3.1` 的 Worker / OffscreenCanvas / WASM、独立 CJK 字体与有界帧缓存,与 PPTX OOXML 解析链路严格分流,并纳入统一缩放、打印、HTML 导出和真实浏览器样例回归(GitHub #123)。Demo、Full、copy-assets、CDN/IIFE 以及 Vue 2.6 + Vue CLI 3 示例都交付经过校验的九文件 `vendor/ppt/` 运行时,标准布局无需手工配置 URL。File Viewer 自身代码仍为 Apache-2.0,PPT 运行时保留包内独立 LICENSE/NOTICE 与公开水印。
* TSV 纳入 Spreadsheet pipeline;格式矩阵更新为 208 个扩展名、25 条预览链路;离线扫描同时阻止 Demo GitHub API 请求和 Typst/Chevrotain 公网默认值进入分发资产。
## `v2.1.30` Full 包完整资产开箱契约 [#v2130-full-包完整资产开箱契约]
* 仅执行 `npm install` 只完成 renderer 代码安装,不会自动把 Worker、WASM、字体和 vendor 文件发布到业务站点;完成下述 Vite、非 Vite 或 `web-full/dist` 交付路径后,才属于完整格式支持。
* 八个 `*-full` 包统一内置 `preset-all` 和同一套运行时资源默认值,PDF、Office、CAD、Typst、Archive、Draw\.io、SQLite 等不再因框架不同而使用不同路径。
* 七个框架 full 包精确依赖同版本 `file-viewer-copy-assets` 并直接提供复制 CLI;`web-full` 的完整 `dist/` 自带全部资源,可原样部署。
* Vite 插件识别 full 包后会在开发和构建阶段自动发布完整资产到部署基址下的 `file-viewer/`;自定义或空 `copyAssets.baseDir` 会同步运行时 URL,非 full 项目保持旧布局。
* Vite 开发服务器会在根路径、子路径、自定义或禁用 `publicDir` 时统一提供资产与完整性清单;`options.pdf.assetBaseUrl` 继续作为 PDF 全量资源覆盖,单项 URL 仍可单独覆盖。
* Svelte 与 Svelte Full 的包根默认导出固定为组件,action/controller 改走明确子路径,避免 Svelte 5 把 action 当组件挂载。
* 修复 CRA/Webpack 常见 `static/js` 及多级 assets 目录被误判为资源根的问题,子路径部署不再把 Worker/WASM 请求到静态脚本目录内。
* 批量发布脚本按 54 个 npm 目标的内部依赖稳定拓扑排序,并在依赖环或重复目标时提前失败。
* 新增八个 full 包资源合约、Vite 子路径与自定义目录、npm/pnpm 冷安装、CLI 完整复制以及真实 PPTX Worker 浏览器回归。
## `v2.1.29` 集中缺陷修复 [#v2129-集中缺陷修复]
* 修复 Vue 2.6 + Vue CLI 3 / webpack 4 示例上传 DOCX 后报 `renderAsync is not a function`(生产压缩后表现为 `u is not a function`):webpack 4 默认选择 `@file-viewer/docx` 的 UMD `browser` 入口,该入口再次经过 Babel 转译后会丢失 CommonJS 导出。
* 旧构建链通过 alias 固定使用 `@file-viewer/docx/dist/docx-preview.mjs`,Word renderer 同时兼容传统 bundler 将 CommonJS API 放在 `default` 的模块形状。
* `pnpm verify:vue26-cli3-office-demo` 不再只验证内置 PDF;冷安装本地 tarball 后会真实上传 DOCX、等待文档页出现,并确认离线 DOCX Worker 被请求。`build`、`noApiBuild`、`nginx` 三种模式均纳入回归。
* 修复标准组件启用 `styleIsolation: 'shadow'` 后 Excel 单元格内容空白(GitHub #117):`e-virt-table` 默认写入 `document.head` 的完整样式无法穿透 ShadowRoot,导致承载单元格文字的 overlayer 失去绝对定位并被画布裁掉。
* Spreadsheet renderer 会识别当前 `e-virt-table` 版本实际注入的完整样式,将其复制到渲染 ShadowRoot,并把 vendor `:root` 变量收敛到 host / `.excel-wrapper`;新增 harness 会先在 npm `2.1.23` 复现空白布局,再验证本地 Vite 开发与生产构建的多 sheet、合并单元格、公式、样式和 overlayer 几何关系。
* 移除 OFD vendor 对 `Array.prototype.pipeline` 的可枚举污染(GitHub #111),避免先加载 OFD 后 PDF.js 把数组误判为非法请求参数;OFD→PDF、PDF→OFD、重复切换和取消均纳入浏览器回归。
* 打印掩膜新增可选的零基 `pageIndex` 并保持旧全局坐标兼容(GitHub #112);浏览模式允许滚轮/触摸翻页,绘制只武装当前页一次,PDF、DOCX、OFD、PPTX 的导出页均提供稳定页索引。
* 修复 Vite 开发入口 `/src/main.*` 被误当成运行时资产目录(GitHub #113):资源基址排除 `/src/`、`/@fs/`、`/@id/`、`/@vite/` 和 `/node_modules/`,根路径/子路径 dev 不再请求 `/src/vendor/pdf` 或触发 fake worker / CMap EOF。
* Archive Worker 与 WASM 统一使用当前文档的运行时资源基址(GitHub #114/#115),同时保留显式绝对 URL 的最高优先级;ZIP、RAR5、7z、加密 ZIP 与 worker 失败边界均使用独立 Vite dev/build harness 验证。
* Vite 插件复制 PDF.js 资产时优先从 PDF renderer 自己的依赖树解析,并校验 API/Worker 版本和来源(GitHub #118);消费项目根安装 `pdfjs-dist 6.x` 时不会再覆盖 renderer 固定的 `5.4.624` worker。
* PPTX renderer 的完成 Promise 现在等待 Worker、整体渲染及异步图表后处理全部结束(GitHub #119);致命错误只触发错误事件,单页错误继续作为警告,切换文件或取消期间的旧任务无法回写完成状态。
* PDF 初始化和 ResizeObserver 统一重放规范化 fit 请求(GitHub #120/#121),保留 `padding`、`maxScale` 与三种 resize 策略;“1:1”固定回到 100%,居中按导航栏后的实际可视区域计算。
* CAD 引擎升级到 `@flyfish-dev/cad-viewer@0.6.6`(GitHub #122),修复 DWG 多段线闭合、保存 UCS/PLAN 初始视图及虚线/点线渲染。
* Web Full、Viewer Demo 和 Component Demo 构建完成后自动净化上游 Chevrotain/Typst 公网默认值;离线扫描只精确豁免 canonical/OG/Twitter 的静态元数据属性,同行运行时 URL 仍会被拦截。
## `v2.1.28` Office 兼容性与 Vite 8 修复 [#v2128-office-兼容性与-vite-8-修复]
* 修复部分 Word/WPS `.doc` 文件仅在行结束标记携带表格属性时,单元格多段落被拆出表格、合并列宽错乱的问题;真实客户附件与合成表格回归均已验证。
* DOCX 引擎升级到 `@file-viewer/docx@0.3.20`,底部图表图例按实际文本宽度整体居中,同时保持右侧饼图图例行为不变。
* 修复 Vite 8 使用 spreadsheet renderer 时 `@xmldom/xmldom` 命名导出未预构建导致的浏览器启动错误,并加入独立 Vite 8 harness 回归。
* 加固离线资产、包体预算与 npm tarball 校验;全仓版本和 workspace 依赖推进到 `2.1.28`。
## `v2.1.27` 关键 PR 修复与缩略图能力 [#v2127-关键-pr-修复与缩略图能力]
* 发布浏览器缩略图生成 API,覆盖 PDF、DOCX、XLSX、EPUB、OFD、Typst、PPTX 等格式,并强化取消、销毁和压缩包资源安全。
* 新增 CBZ/CBR 漫画阅读器,支持自然顺序、按钮/键盘/滑动导航及旧渲染会话清理。
* 修复 DOC 表格外边框继承与 Demo 集成 UI,补齐桌面/移动端回归验证。
* 版本提升至 `2.1.27`,用于避免覆盖 registry 中已有的旧 `2.1.26` 产物。
## `v2.1.26` 超大文本稳定浏览与主题切换 [#v2126-超大文本稳定浏览与主题切换]
* 全仓版本、workspace 依赖和 release matrix 推进到 `2.1.26`。
* 文本、代码和 Markdown 超过 512 KiB 后自动使用稀疏行索引与有界虚拟滚动,不再一次性解码、高亮并挂载完整文件;52 万行代码、超长单行、全文搜索和尾部跳转均纳入真实 Chromium 回归。
* 工具栏新增可配置的手动浅色/深色切换按钮,支持 `toolbar.theme` 和 `toolbar.order`,并在重新渲染后恢复阅读位置(GitHub #97)。
* 发布已包含 DOCX / XLSX 图表预览修复及对应样例回归(GitHub #96)。
* GitHub 默认 `README.md` 改为 English,中文入口迁移到 `README.zh-CN.md`;中英文页面分别只展示对应语言的 Demo GIF。
## `v2.1.25` PDF 渲染器兼容性修复 [#v2125-pdf-渲染器兼容性修复]
* 全仓版本、workspace 依赖和 release matrix 推进到 `2.1.25`。
* 修复 UMI v4 项目启动报错 `Invalid regular expression flag`(GitHub #98):`@file-viewer/renderer-pdf` 改为固定使用 `pdfjs-dist@4.10.38`,不再依赖新版 PDF.js 才需要的 JBIG2/OpenJPEG/QCMS/QuickJS wasm 辅助模块,PDF wasm 资源清单调整为可选(`required: false`)。
* 修复生产环境部署到二级路径(如 nginx 反代 `/workspace/`)时 PDF worker 路径解析错误(GitHub #99):worker、cMap、标准字体等 PDF 资源统一按 `document.baseURI` 解析,移除单独的"仅站点根目录"回退逻辑,与其他渲染器的资源路径解析行为保持一致。
* 同步刷新 `pdf.worker.mjs` 等本地 vendor 资源与 CAD wasm 拷贝脚本。
## `v2.1.24` OFD 签章、DOC/PPTX 修复与打印体验 [#v2124-ofd-签章docpptx-修复与打印体验]
* 全仓版本、workspace 依赖和 release matrix 推进到 `2.1.24`。
* 修复 OFD 预览不显示电子签章(GitHub #94):恢复 SES 签章外观解析,支持 PNG/JPEG 与嵌套 OFD 印章叠加。
* 修复 DOCX 导出/打印 HTML 图片空白(GitHub #90):`blob:` 图片自动内联为 `data:` URL。
* 打印链路默认携带水印;新增掩膜打印与移动端打印下拉向上展开。
* 修复 `.doc` 内嵌 OfficeArt 图片解析(GitHub #87)与工具栏缩放按钮位移(GitHub #88)。
* 修复 PPTX Origin OLE EMF 图表渲染与空白 run 保留;DOCX 暗黑模式与远程 URL 规范化。
## 当前主线 OFD 电子签章预览 [#当前主线-ofd-电子签章预览]
* 修复 OFD 预览不显示电子签章的问题(GitHub #94):恢复 SES `SignedValue` 签章外观解析,支持 PNG/JPEG 印章图片与嵌套 OFD 印章,并按 `StampAnnot` 边界叠加到对应页面。
* 预览路径只提取印章外观,不做国密/证书验签,单个签章失败不会阻断正文渲染;新增 `seal-png.ofd` / `seal-ofd.ofd` 回归与 `pnpm --filter @file-viewer/renderer-ofd verify:github-94`。
## 当前主线 DOCX/导出 HTML 图片修复 [#当前主线-docx导出-html-图片修复]
* 修复 DOCX 导出 HTML / 打印时图片空白的问题(GitHub #90):`@file-viewer/docx` 预览默认使用会话级 `blob:` URL,导出克隆后在新文档中失效。
* 在 core 导出/打印统一链路把 `blob:` 内联为可移植的 `data:` URL,并在 adapter 导出前等待图片就绪;同一修复覆盖打印窗口与 HTML 下载。
## 当前主线打印水印与打印掩膜 [#当前主线打印水印与打印掩膜]
* 打印链路默认附带当前水印样式(`print-color-adjust: exact`),避免浏览器打印时丢掉水印层(GitHub #92)。
* 工具栏打印改为紧凑下拉:点击「打印」后可选「直接打印」或「掩膜打印」;掩膜打印进入拖拽黑块设计流程,确认后再打印。
* 移动端底部操作面板与浮动工具栏的打印下拉改为向上展开,避免盖住底部快捷入口或被裁切。
* 掩膜设计器通过 core 内部动态 `import('./print-mask')` 异步加载,不打进主包;组件侧统一调用 `printWithMask()` / `printRenderedHtml({ mask })`,安装组件即可开箱使用,无需用户配置 `@file-viewer/core/print-mask` 子路径 alias。
* 打印 HTML 在内容之上、水印之下叠加黑色遮盖块。
## 当前主线 `.doc` 内嵌图片解析修复 [#当前主线-doc-内嵌图片解析修复]
* 按 MS-DOC `PICFAndOfficeArtData` / MS-ODRAW OfficeArt BLIP 规范解析内嵌图片,不再只靠魔数扫描;修复把 OfficeArt 内嵌 PNG/JPEG 误判为 `image/emf` 或 `application/octet-stream`,导致浏览器空白占位的问题(GitHub #87)。
* 新增 OfficeArt FBSE/BLIP 提取、DIB→BMP、压缩 EMF/WMF zlib 解压与 SVG 转换,以及 PICF 显示尺寸(`dxaGoal`/`dyaGoal`/`mx`/`my`)应用到 ``。
* 增加 `image-embedded.doc` 回归 fixture 与 `pnpm --filter @file-viewer/doc verify:github-87`,锁定 PNG/JPEG 内嵌图可解析、可渲染。
## 当前主线工具栏缩放按钮位置修复 [#当前主线工具栏缩放按钮位置修复]
* 修复默认工具栏从 100% 点击“放大”后,“1:1”还原按钮精确出现在“放大”按钮原位置,导致连续点击时第二次点击变成误触发“还原”而非继续放大的问题(GitHub #88):工具栏为右对齐布局,且两个图标按钮宽度相同,原实现把“1:1”插入在“放大”按钮之后,右对齐重排会让“放大”整体左移一个按钮宽度,新按钮正好顶替上“放大”刚才的像素位置。
* 调整为“1:1”按钮插入在“放大”按钮之前,让“放大”按钮始终保持工具栏最右侧的锚点位置,显示/隐藏“1:1”不再引起它的位移;新增 DOM 顺序回归测试和真实浏览器坐标验证,锁定该行为避免回归。
## 当前主线 DOCX 暗黑模式适配 [#当前主线-docx-暗黑模式适配]
* DOCX 渲染引擎升级到 `@file-viewer/docx@0.3.18`,同步刷新 `vendor/docx/docx.worker.js` 和缓存版本参数,确保本地 Demo、web viewer 与 compat viewer 使用同一版离线 Worker。
* `options.theme: 'dark'` 会自动启用 DOCX 暗黑渲染;`theme: 'light'` 保持浅色文档面;`theme: 'system'` 继续跟随浏览器 `prefers-color-scheme`。需要业务强制覆盖时可设置 `options.docx.darkMode: true / false`。
* 新增 DOCX 暗黑样式回归断言,覆盖 viewer 背景、DOCX 包裹层、文档页颜色和 `color-scheme`,避免暗色模式下出现白块、透明底或文字对比度异常。
## `v2.1.20` 压缩包中文文件名与 full 资产路径修复 [#v2120-压缩包中文文件名与-full-资产路径修复]
* 修复未声明 UTF-8 的 GBK/GB18030 ZIP 文件名乱码问题,兼容客户压缩包中中文文件名目录展示。
* 区分旧编码 ZIP 的兼容解码路径和真正的 libarchive Worker 失败,避免错误显示 “libarchive Worker 未能启动” 提示。
* Vue 3 / Vue 2.7 / Vue 2.6 full 包默认补齐 `/file-viewer/` 下的 Archive、PDF、Office、CAD、Typst 等离线资产 URL,并保留自定义 asset base URL 能力。
## 当前主线官方 Demo iframe 交付包 [#当前主线官方-demo-iframe-交付包]
* 新增 `iframe.html` 作为官方 Demo 的无外壳嵌入入口,支持 `?url=...` 直接预览业务文件,也支持 `?from=<父页面 origin>&name=<文件名>` 后由父页面 `postMessage(Blob)` 传入二进制文件;原主 Demo `index.html` 保留同一套协议,兼容既有集成。
* 新增 `file-viewer-v2-*-official-demo-iframe.tar.gz` release artifact,包内包含官方 Demo 构建产物、`iframe-example.html`、`README.iframe.md`、`iframe-manifest.json`、示例文件和离线 Worker/WASM/vendor 资源,客户可直接私有化部署。
* `release:standard:build`、`release:public`、`verify:demo-output`、`verify:demo-iframe-artifact` 和公开仓 `release-manifest.json` 校验全部纳入该产物,避免后续发布漏带官方 iframe Demo 包。
## `v2.1.19` fit 适配与 Shadow DOM provider 补强 [#v2119-fit-适配与-shadow-dom-provider-补强]
* 在 `v2.1.18` 离线资产发布基础上继续推进全仓版本到 `2.1.19`,确保最新源码、npm 包、公开仓、Release 资产和文档矩阵保持同一发布口径。
* core 的搜索、缩放和视图状态 provider 查找支持穿透 open ShadowRoot,Web Component / Shadow DOM 隔离模式下的工具栏、fit 和状态同步不再丢失内部 renderer provider。
* 图片、DOC 和 DOCX renderer 接入专属 fit provider,`fit:'width'`、`contain`、`scale-down` 等模式会基于真实图片尺寸或文档页面尺寸计算绝对缩放;图片未加载和文档暂不可测时会自动重试。
* 新增 ShadowRoot provider 回归测试,覆盖 provider 注册、查找和注销链路,避免样式隔离/组件封装后核心操作能力退化。
## `v2.1.18` 离线资产、本地化发布与 DOCX 引擎更新 [#v2118-离线资产本地化发布与-docx-引擎更新]
* 全仓版本、workspace 依赖和 release matrix 推进到 `2.1.18`;当前矩阵覆盖 52 个 npm 发布目标、16 个组件目标、27 条 smoke 渲染链、24 个 renderer pipeline、206 个扩展名和 432 个组件渲染目标。
* `libarchive.js` Worker / WASM 改为发布前自动从当前 lockfile 固定版本同步到 demo、component demo、web viewer、compat viewer 和 web-full 产物,`release:standard:preflight` 会强制校验这些本地资产,压缩包运行时不再依赖外部地址。
* 全仓离线运行时扫描扩展到 core、renderer、preset、组件、compat、demo public/dist 和 full IIFE async renderer 产物;默认禁止 CDN、官方域名 fallback 和第三方在线服务引用,Geo 默认公开底图作为明确例外保留。
* DOCX 渲染引擎升级到 `@file-viewer/docx@0.3.17`,同步刷新 `vendor/docx/docx.worker.js`、`jszip.min.js` 和缓存版本参数,确保 npm 包、demo、component demo、web viewer 和 web-full 都拿到同一版离线 Worker 资产。
* `sanitize:release-dist` 覆盖 public 与 dist 两类运行时资产,避免 `prepare-viewer` 或 full IIFE 构建后重新带入 Typst 字体 CDN、Chevrotain diagram CDN、Draw\.io 远端 fallback 等外链标记。
* Web Component / IIFE / web-full 默认走 Shadow DOM 样式隔离,框架组件可通过 `options.styleIsolation:'shadow'` opt-in;README、生态组件 README 和文档站同步说明 tokens、parts、hostile CSS 验证和旧 light DOM 兼容路径。
## 当前主线 ViewerOptions.fit 统一适配能力 [#当前主线-vieweroptionsfit-统一适配能力]
* `ViewerOptions` 新增 `fit`,支持 `auto`、`contain`、`cover`、`width`、`height`、`actual` 和 `scale-down`;未传 `fit` 时继续保持各 renderer 历史首屏行为,避免轻量接入被默认策略改变
* `fit` 对象形态支持 `{ mode, resize, padding, minScale, maxScale }`,其中 `resize` 默认 `until-interaction`:首屏和容器变化自动适配,用户手动缩放、平移或恢复视图后停止覆盖用户视角
* core 扩展 zoom / view-state provider 合约,新增 `fitToView()` controller/ref API 和 `fit-change` 事件;Web Component 支持 ``
* PDF、图片、CAD、XMind、Geo 和 3D renderer 接入专属 fit provider,其他标准 renderer 通过通用 view-state provider 走内部 zoom provider 兜底;压缩包和邮件内嵌预览继承父级 `options.fit`
* Demo 新增 fit 模式切换入口;显式 fit、resize、用户缩放暂停自动适配和 `fitToView()` 主动重算纳入通用浏览器 smoke / release matrix 体系,避免长期保留一次性 issue 验证入口
## 当前主线工具栏定制能力 [#当前主线工具栏定制能力]
* `toolbar.position` 新增 `top-center`,支持顶部操作栏水平居中;原有 `top` 继续保持顶部靠右,`auto` 和 `bottom-right` 行为不变,兼容已有接入
## 当前主线视图状态同步能力 [#当前主线视图状态同步能力]
* 新增统一 `initialViewState`、`view-state-change`、`getViewState()` 和 `applyViewState()` 协议,面向投屏、远端协同、双栏对比和阅读进度恢复
* 所有标准 renderer loader 自动注册通用 view-state provider,未写专属适配的格式也能记录 / 恢复 renderer、缩放和滚动比例
* PDF 提供页码、页数、缩放、旋转、滚动和导航状态;XMind、Geo、3D、CAD 追加画布 pan、地图中心、相机视角或底层视图快照等高交互状态
* 程序化恢复使用 `source: 'api'` / `action: 'restore'`,并抑制中间滚动和缩放回弹事件,避免操作端和展示端互相触发
* README、中英文使用文档、快速开始和格式能力页已统一说明 view-state、真实 zoom 状态和 PPTX Worker 自托管配置,方便几轮修复后对外口径保持一致
## 当前主线缩放状态准确性修复 [#当前主线缩放状态准确性修复]
* core 的 zoom controller 会订阅 renderer provider 的异步状态变更,首屏自适应、容器 resize 和内部重排后同步抛出真实 `zoom-change`
* `getOperationAvailability()` / `operation-availability-change` 会结合当前 `zoomState` 动态计算 `zoomIn`、`zoomOut`、`zoomReset`,各生态组件和自定义工具栏不再拿到静态缩放能力
* PDF、Word/DOCX、DOC 和图片预览修正首屏 fit 后的真实比例、缩放步进和 reset 状态,避免显示默认 `100%` 或点击缩放时来回跳
* 新增 `pnpm verify:zoom-state` 浏览器回归,覆盖 DOCX、PDF 和图片的首屏比例、内部 scale 与工具栏显示一致性
## `v2.1.9` OFD 资源路径解析加固 [#v219-ofd-资源路径解析加固]
* OFD renderer 加固电子发票资源路径归一化和查找逻辑,兼容 `DocumentRes`、`PublicRes`、`BaseLoc`、大小写差异和缺失目录等组合场景
* 修复部分 OFD 文件读取图片资源时因路径解析失败抛出 `Cannot read properties of undefined (reading 'async')`,导致整份文档无法预览的问题
* 缺失或异常资源继续降级跳过,保证可解析页面主体优先展示
## `v2.1.8` OFD 电子发票兼容与压缩包内嵌预览修复 [#v218-ofd-电子发票兼容与压缩包内嵌预览修复]
* OFD renderer 兼容多个并列 `ofd:Fonts`、`ofd:DrawParams`、`ofd:MultiMedias` 资源分组,修复部分电子发票在读取图片资源时抛出 `Cannot read properties of undefined (reading 'format')` 的问题
* OFD 图片资源渲染增加缺失资源兜底,单个资源异常不会中断整份文档正文预览
* PDF renderer 默认静态 `vendor/pdf/pdf.worker.mjs` 不存在或被网关回退成 HTML 时,会自动懒加载包内 PDF.js worker handler 兜底,修复轻量 `@file-viewer/vue3` / `@file-viewer/web` + `@file-viewer/preset-office` 接入时因未复制 viewer assets 导致 `Setting up fake worker failed` 的问题;显式 `options.pdf.workerUrl`、Vite 插件和 `file-viewer-copy-assets` 仍优先使用真实 Worker
* 压缩包预览支持隐藏/显示内部文件列表,长文件名自动省略,避免移动端和窄容器下把页面挤出视图
* `@file-viewer/web-full` IIFE 嵌套预览继续使用当前已安装的 renderer / preset 上下文,压缩包内 PDF、Office、图片等文件不再误判为缺失 renderer
## 当前主线 GitHub 曝光与长期运营资产优化 [#当前主线-github-曝光与长期运营资产优化]
* README 首屏改为“面向企业后台、内网和私有化系统的纯前端文件预览组件”,把无需服务端转码、Demo、文档、快速开始和支持格式前置,把 206 个扩展名作为可信度证据承接
* 新增 `CONTRIBUTING.md`、`SUPPORT.md`、`SECURITY.md`、`CODE_OF_CONDUCT.md`、`ROADMAP.md`、根 `CHANGELOG.md`、Issue 模板和 PR 模板,方便收集真实业务文件兼容性反馈
* 文档站新增方案对比页,克制说明 File Viewer、服务端转码和 Office Online / 云服务的适用边界
* 新增 `RELEASE_TEMPLATE.md`,沉淀 Release 写法、Topics、Social Preview 和版本发布节奏
* 新增 GitHub Wiki 同步链路,将完整中英文文档以 Wiki 页面保留在 GitHub,和官网文档站形成双入口
## `v2.1.6` Vite 插件 PDF 资产复制与移动端接入说明修复 [#v216-vite-插件-pdf-资产复制与移动端接入说明修复]
* `@file-viewer/vite-plugin` 的依赖解析改为递归锚点发现:在 pnpm / yarn PnP 风格严格依赖场景下,即使业务只直接安装 `@file-viewer/react`、`@file-viewer/preset-office` 和 `@file-viewer/vite-plugin`,插件也能从 preset 依赖链继续定位 `@file-viewer/renderer-pdf` 与 `pdfjs-dist`,正确复制 `vendor/pdf/pdf.worker.mjs`、CMap、WASM 和 standard fonts
* 新增插件回归用例,模拟 React/Vite 项目中 renderer 只挂在 preset 依赖下的安装结构,验证 `copyAssets:true` 能在 dev publicDir 中生成完整 PDF 离线资源
* React 快速开始补充手机浏览器、H5 WebView 与 React Native WebView 接入说明,明确容器高度、`100dvh`、安全区、右下角工具栏、内部缩放 provider 和自托管 Worker/WASM 资源的推荐配置
## `v2.1.5` DOCX Electron 兼容与 Excel 图片滚动层级修复 [#v215-docx-electron-兼容与-excel-图片滚动层级修复]
* DOCX Worker 默认改为自动环境检测:HTTP/HTTPS 部署继续启用 Worker,Electron `file://`、`about:`、`data:` 等不安全本地协议会自动回退到主线程解析,避免本地预览长时间等待 Worker 握手;显式 `options.docx.worker: true / false` 仍拥有最高优先级
* DOCX Worker 默认超时调整为 5000ms,静态资源路径、MIME、CSP 或 WebView 不兼容时更快回退,减少用户误判为页面卡死的等待时间
* Excel / XLSX 图片浮层限制在真实单元格内容区,并为右侧/底部滚动条预留安全交互区域,修复图片覆盖表格滚动条导致滚动困难的问题
## `v2.1.4` 文档首页专业化与 IIFE 按格式异步加载 [#v214-文档首页专业化与-iife-按格式异步加载]
* 文档站首页重构为能力驱动入口,首屏突出浏览器端文件预览基础设施、多格式覆盖、统一交互、模块化装配、离线资源和企业部署能力,避免只围绕快速开始展开
* 中英文文档首页同步新增核心能力区,说明高还原格式链路、按需性能策略、搜索/缩放/打印/导出/水印等统一交互,以及公网、内网、Docker、Cloudflare Pages、Release 包和私有 CDN 的交付边界
* `@file-viewer/web-full` IIFE 首包改为只注册 Custom Element、controller 和 lazy full preset;PDF、Word、Excel、CAD、Typst、压缩包等重型 renderer 会在命中文件类型时异步加载 `dist/renderers/*.iife.js`
* Worker、WASM、字体、PDF cMap、CAD、Typst、Archive、Docx、Excel 和 Draw\.io 离线资源继续按脚本 URL 自动解析,保持 CDN 与企业自托管一致体验
## `v2.1.3` CDN 全量接入与生态 full 包 [#v213-cdn-全量接入与生态-full-包]
* 新增 `@file-viewer/web-full`、`@file-viewer/vue3-full`、`@file-viewer/vue2.7-full`、`@file-viewer/vue2.6-full`、`@file-viewer/react-full`、`@file-viewer/react-legacy-full`、`@file-viewer/jquery-full` 和 `@file-viewer/svelte-full`,面向“先验收完整能力,再按业务边界裁剪”的快速接入场景
* `@file-viewer/web-full` 提供 CDN / script 标签完整格式入口,IIFE 包会根据脚本地址自动定位随包分发的 Worker、WASM、字体、PDF cMap、CAD、Typst、Archive、Docx、Excel 和 Draw\.io 离线资源,适合公网 CDN 与企业自托管两种模式
* 保留原有轻量组件包与 `preset-lite` / `preset-office` / `preset-engineering` / `preset-all` 的按需组合模式;文档和 README 前置说明“轻组件 + preset / renderer”的推荐边界,避免把 full 包误用为所有业务的默认选择
* Vanilla JS 快速开始补齐无组件命令式 `mountViewer` 示例;Vue3、Vue2.7、Vue2.6、React、React Legacy、Svelte、jQuery 的快速开始均补齐 full 包与按需包两条路径
* 生态包校验扩展到 50 个发布目标,覆盖标准组件、完整 full 包、核心、renderer、preset、Vite 插件与历史兼容 alias;发布链路同步构建 Demo、官网、文档站、开源总仓和 npm
## `v2.1.2` 压缩包内嵌预览、移动端 PDF 与安装口径修复 [#v212-压缩包内嵌预览移动端-pdf-与安装口径修复]
* 压缩包内嵌 PDF / Office / 图片等文件预览会清理父级压缩包的 `url` / `streamUrl`,避免内部 PDF 误读取外层 `.zip` / `.rar` 流导致 `Invalid PDF structure` 或 `Bad FCHECK in flate stream`
* 移动端 PDF 预览在窄屏默认收起页侧边栏并压缩工具栏高度,避免导航面板遮挡页面主体;显式 `options.pdf.defaultNavigationVisible` 仍可覆盖默认行为
* 快速开始、生态总览和 README 将“轻组件包 + preset / renderer 格式能力层”的安装边界前置说明,明确 `@file-viewer/vue3` 等组件包最轻,`preset-all` 是完整 Demo / 内部全格式入口而非所有业务默认选择
* 发布前回归覆盖 `archive` 嵌套渲染上下文、core preset 自动装配、文档构建、Demo 构建、官网构建、离线资源校验、安装体积预算和冷安装时间;`vue3 + preset-all` 最重冷安装目标通过
* 全线生态包、Demo、文档站、官网和开源总仓同步推进到 `2.1.2`
## `v2.1.1` GitHub issue 回归修复与发布同步 [#v211-github-issue-回归修复与发布同步]
* `@file-viewer/vite-plugin` 新增 preset 自动发现与默认 HTML 注入;安装 `@file-viewer/vue3` 等组件包并安装 `@file-viewer/preset-office` / `preset-engineering` 后,框架组件可通过 `autoRenderers` 自动获得对应预览能力,仍保留 `inject:false`、`autoRenderers:false` 和 `rendererMode:'replace'` 的手动控制路径
* core 缺失 renderer 状态改为区分“支持矩阵内但未装配”和“真正不支持”:如 `.pdf` 未装配时提示安装 `@file-viewer/preset-office` 或 `@file-viewer/renderer-pdf`,避免用户误解为产品不支持该格式
* Markdown 预览自动剥离文件开头 YAML Frontmatter,避免元数据被当作正文渲染,同时保留正文中的普通分隔线
* PDF 默认 Worker、cMap、WASM 和标准字体资源改为站点根路径解析,兼容 Vite / Vue Router / React Router 等深层路由部署
* Excel / XLSX worker 将图片 drawing anchor 纳入虚拟表格尺寸计算,修复图片位于数据区下方时无法继续向下滚动的问题
* 工具栏新增 `toolbar.items` 与 `toolbar.permissions`,同时保留 `beforeOperation` / `toolbar.beforeOperation` 作为异步鉴权和确认拦截点
* 全线生态包、Demo、文档站、官网和公开总仓同步推进到 `2.1.1`
## `v2.1.0` 模块化架构与文档门户专业化 [#v210-模块化架构与文档门户专业化]
* 全仓 workspace、标准组件包、renderer、preset、兼容 alias、Demo、官网和文档站版本统一推进到 `2.1.0`
* 对外重点明确为模块化架构:`@file-viewer/core` 负责底层协议和统一 API,重型格式能力进入独立 renderer,`preset-lite` / `preset-office` / `preset-engineering` / `preset-all` 按产品形态组合,各生态组件保持原生体验
* README 头部补齐品牌图标、GitHub / npm / Docs / Demo / Release / Docker / License / 格式矩阵 badge,并把 Demo GIF 前置,降低用户理解成本
* README 与文档站补齐最小化引入和组合引入的详细步骤,说明 `@file-viewer/vite-plugin`、`formats`、`preset`、`copyAssets`、`virtual:file-viewer-renderers`、`builtinRenderers:'none'` 和 `rendererMode:'replace'` 的推荐搭配
* 文档站首页移除嵌入 Demo 的 iframe,改为 GIF 展示、模块化接入路径和更专业的文档导览;官网 `file-viewer.app` 改为嵌入 `doc.file-viewer.app`,让门户和文档站关系更紧密
* 对外 npm 生态口径更新为 50 个发布目标:45 个标准组件/完整 full 包/核心/renderer/preset/工程插件包 + 5 个历史兼容 alias
## 当前主线 XMind、EDA 版图与表格列宽体验补齐 [#当前主线-xmindeda-版图与表格列宽体验补齐]
* 新增 PSD 高保真图层预览,`@file-viewer/renderer-data` 在命中 `.psd` 时才按需加载 `ag-psd`,支持图层选择显隐、画布重绘、统一缩放、主题隔离和 HTML 导出边界说明
* 新增 Mermaid / PlantUML 绘图预览,`@file-viewer/renderer-drawing` 在命中 `.mermaid` / `.mmd` / `.plantuml` / `.puml` 时才分别加载官方 Mermaid renderer、`plantuml-encoder` 与 Panzoom;PlantUML 默认离线源码预览,需要完整服务端 SVG 时可通过 `options.drawing.plantumlServerUrl` 指向自托管服务
* 新增 Git patch 和 Git bundle 预览,`@file-viewer/renderer-text` 对 `.patch` 按需加载 `diff2html` 输出左右比对,对 `.bundle` / `.bdl` 解析 refs、提交历史、文件树和可读 blob 内容,并在浏览器端还原常规 OFS_DELTA / REF_DELTA 对象
* UMD 电子书从 core 迁移到 `@file-viewer/renderer-epub`,与 EPUB 共用电子书 renderer 包;`@file-viewer/core` 运行时依赖归零,`pako` 仅在打开 UMD / Git bundle 等相关 renderer chunk 时加载
* 支持格式矩阵更新为 206 个扩展名、24 条预览链路;Demo 新增 PSD、Mermaid、PlantUML、patch 和 git bundle 示例,Vite 插件、bundle budget、组件 README 与文档站口径同步
* XMind 画布交互切换为轻量成熟的 `@panzoom/panzoom`,保留 `@ljheee/xmind-parser` 的 XMind 8 XML / XMind 2020+ JSON 解析链路,拖拽平移、节点起手拖拽、移动端双指缩放、滚轮锚点缩放、键盘平移、适配画布和 toolbar 状态同步由统一 Panzoom 状态驱动;浏览器 smoke 已加入真实鼠标拖拽断言
* `@file-viewer/eda-layout` 新增 OASIS 可读文本夹具解析,OAS/OASIS demo 不再只是结构提示,能够在浏览器里输出 SVG 版图;真实 SEMI 二进制 OASIS 仍保持安全结构索引、可读字符串、实体候选和诊断边界,后续完整几何继续走独立 WASM/增量渲染内核路线
* 新增 `@file-viewer/renderer-presentation` 独立 renderer 包,基于 `@file-viewer/pptx` 提供 PPTX / PPTM / POTX / POTM / PPSX / PPSM 按需预览、缩放、打印和 HTML 导出;`@file-viewer/preset-all` 与 `@file-viewer/vite-plugin` 已优先聚合该包,ODP 继续走 OpenDocument 兼容链路
* `@file-viewer/core` 移除 `@file-viewer/pptx` 直接依赖和内置 PPTX handler,PowerPoint 完整预览统一通过 `@file-viewer/renderer-presentation` 或 `@file-viewer/preset-all` 装配,core 直接渲染依赖从 37 降到 36
* 新增 `@file-viewer/renderer-word` 独立 renderer 包,承接 DOCX / DOCM / DOTX / DOTM、DOC / DOT、RTF 和 ODT 预览链路;`@file-viewer/core` 移除 `@file-viewer/docx`、`msdoc-viewer`、`rtf.js`、`linkedom` 和 `@xmldom/xmldom` 直接依赖,Word 完整预览统一通过 `@file-viewer/renderer-word` 或 `@file-viewer/preset-all` 装配,core 直接渲染依赖从 36 降到 31
* XMind 已从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `@ljheee/xmind-parser`;完整脑图预览统一由 `@file-viewer/renderer-mindmap` 或 `@file-viewer/preset-all` 装配,core 直接渲染依赖从 31 降到 30
* 地理数据已从 core 兼容入口中移出,`@file-viewer/core` 不再默认安装 `@tmcw/togeojson`、`shpjs`、`maplibre-gl` 和 `proj4`;GeoJSON / KML / GPX / SHP 预览统一由 `@file-viewer/renderer-geo` 或 `@file-viewer/preset-all` 装配,core 直接渲染依赖从 30 降到 28
* HEIC / HEIF 转换能力已从 core 轻量图片入口中移出,`@file-viewer/core` 不再默认安装 `heic2any`;普通图片仍保留浏览器原生预览,HEIC / HEIF 和完整图片链路统一由 `@file-viewer/renderer-image` 或 `@file-viewer/preset-all` 装配,core 直接渲染依赖从 28 降到 27
* Vue3 原生组件渲染桥接层改为按当前 `options.renderers`、`options.rendererMode` 和 `options.builtinRenderers` 创建临时 renderer registry,`@file-viewer/preset-all` / 独立 renderer 包会在组件路径真实生效,避免 XMind、Geo、HEIC 等已从 core 移出的格式在 Demo 中误显示“不支持”
* 新增 `@file-viewer/renderer-drawing` 独立 renderer 包,覆盖 Draw\.io / diagrams.net 离线 viewer、Excalidraw rough.js 只读 SVG 兜底、统一缩放、打印和 HTML 导出,并由 `@file-viewer/preset-all` 与 `@file-viewer/vite-plugin` 自动聚合
* 新增 `@file-viewer/renderer-3d` 独立 renderer 包,基于 Three.js loaders 承接 GLTF/GLB、OBJ、STL、PLY、FBX、DAE、3DS、3MF、USD/USDZ、点云和 VTK 等 WebGL 预览,并由 `@file-viewer/preset-all` 与 `@file-viewer/vite-plugin` 自动聚合
* 新增 `@file-viewer/renderer-data` 独立 renderer 包,承接字体、PSD、AI/EPS、SQLite、Parquet、Avro、WASM 和 WebArchive 的安全结构预览,SQLite WASM 由 `@file-viewer/vite-plugin` 复制到离线 assets
* 新增 `@file-viewer/renderer-eda` 独立 renderer 包,承接 OLB、DRA、GDSII、OASIS 结构预览;标准 GDSII 可用纯前端记录解析生成 SVG 快速版图,大元素集会自动切到 WebGL canvas,OASIS / Cadence 高保真几何继续按独立 WASM 内核路线维护
* 新增 `@file-viewer/eda-layout` 与 `@file-viewer/eda-orcad` 两个 EDA engine package;GDSII/OASIS 版图底层能力、OrCAD/Allegro 二进制检查能力从 UI renderer 中拆出,GDSII WebGL typed-array 批次已有独立门禁,后续 OASIS WASM 或逐步 TS 移植可以独立发布、独立回归
* 复核 XMind、GDSII/OASIS、OLB/DRA 等新增复杂格式的公开生态与 WASM/手写解析路线,明确 GDSII 是当前正式快速预览,OASIS 文本夹具可真实出图,真实二进制 OASIS/OLB/DRA 仍属于结构预览和后续独立 WASM 内核路线;同时把 XMind `pan` 写入 smoke matrix 显式断言,真实浏览器 smoke 已覆盖 Pointer 与真实鼠标拖拽路径
* 按需渲染架构计划补齐为可执行路线图,明确轻 core、独立 renderer、preset 编排、Vite 插件自动装配、renderer 交付契约、core 依赖预算和终态验收门禁;新增 `verify:core-dependency-budget`、`verify:renderer-contracts`、`verify:renderer-assets`、`verify:install-budget` 与 `verify:bundle-budget`,后续以清理 core 直接重依赖和守住首屏入口体积为 2.x 主治理线
* 支持格式矩阵保持 206 个扩展名、24 条预览链路,新增 XMind 脑图、Mermaid / PlantUML、Git patch / bundle 和 PSD 图层预览,并将 EDA 安全结构索引扩展到 GDSII / OASIS 版图文件;`brep` 进入 3D 工程模型入口
* `.xmind` 基于 `@ljheee/xmind-parser` 离线解析 XMind 8 XML 与 XMind 2020+ JSON 包结构,支持多 sheet、节点、标签、备注、链接、标记、图片、目录树、Panzoom 拖拽平移、移动端双指缩放、适配画布、搜索、缩放、打印和 HTML 导出
* 优化 XMind 画布平移体验,使用 Panzoom 替代脆弱的手写输入状态机,支持移动端 pinch zoom、Ctrl/Command 滚轮锚点缩放、键盘方向键平移和双击适配视图,拖拽中禁用链接命中并禁用浏览器原生拖图/拖链接,边界约束改为画布式保留可见边缘
* XMind 浏览器 smoke 已增加 Pointer、节点起手、滚轮平移和真实鼠标拖拽断言
* XMind 平移、目录定位和键盘方向键移动后会同步通知统一缩放 toolbar,外部 `resetZoom()` / `getZoomState()` 能正确感知“已平移但比例未变化”的状态
* XMind 官方 Demo 样例已通过真实浏览器回归:`.xmind` 能由 `@file-viewer/renderer-mindmap` 正常接管,拖拽后画布 transform 发生平移变化,证明组件层 preset 装配和 renderer 内部 pan 交互同时生效;浏览器冒烟脚本也会对 `.xmind` 执行 PointerEvent 拖拽断言
* XMind 增加 ResizeObserver 视口适配策略:首次打开和宿主容器尺寸变化会自动适配画布,用户手动拖拽、滚轮或缩放后保留当前视角,只做安全边界校正,避免脑图在移动端、嵌入容器和响应式布局中“拖不动”或 resize 后视角丢失
* 代码与 Markdown 预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `highlight.js` 和 `marked`;完整文本预览统一由 `@file-viewer/renderer-text` 或 `@file-viewer/preset-all` 装配,core 直接渲染依赖从 27 降到 25,Phase 3 依赖预算从 10 降到 8
* 音视频预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `hls.js` 和 `@tonejs/midi`;MP3/WAV/OGG/MIDI/MP4/WEBM/HLS 完整媒体能力统一由 `@file-viewer/renderer-media` 或 `@file-viewer/preset-all` 装配,core 直接渲染依赖从 25 降到 23,Phase 3 依赖预算从 8 降到 6
* 3D 模型与绘图预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `three`、`@excalidraw/excalidraw` 和 `roughjs`;GLB/GLTF/STL/OBJ/FBX/DAE/3MF/VTK 等模型由 `@file-viewer/renderer-3d` 装配,Draw\.io / Excalidraw / Mermaid / PlantUML 由 `@file-viewer/renderer-drawing` 装配,core 直接渲染依赖从 23 降到 20,Phase 3 依赖预算从 6 降到 3
* 压缩包、邮件和 EPUB 预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `libarchive.js`、`postal-mime`、`@kenjiuno/msgreader` 和 `epubjs`;Archive / Email / EPUB 完整能力统一由 `@file-viewer/renderer-archive`、`@file-viewer/renderer-email`、`@file-viewer/renderer-epub` 或 `@file-viewer/preset-all` 装配,core 直接运行时依赖从 20 降到 16,Phase 3 依赖预算从 3 降到 0
* 数据资产与 EDA 预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `ag-psd`、`sql.js`、`hyparquet`、`avsc` 和 `cfb`;PSD / SQLite / Parquet / Avro / OLB / DRA / GDSII / OASIS 完整能力统一由 `@file-viewer/renderer-data`、`@file-viewer/renderer-eda` 或 `@file-viewer/preset-all` 装配,core 直接运行时依赖从 16 降到 11,Phase 4 依赖预算归零
* PDF 预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `pdfjs-dist`;PDF 页面渲染、导航、目录、搜索、缩放、打印和导出统一由 `@file-viewer/renderer-pdf` 或 `@file-viewer/preset-all` 装配,core 直接运行时依赖从 11 降到 10,Phase 2 依赖预算从 10 降到 9
* OFD 预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `jszip`、`ofd-xml-parser` 和 DLTech21/ofd.js vendor;OFD 页面渲染、缩放、打印和导出统一由 `@file-viewer/renderer-ofd` 或 `@file-viewer/preset-all` 装配,core 直接运行时依赖从 10 降到 8,Phase 2 依赖预算从 9 降到 7
* Typst 预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `@myriaddreamin/typst.ts`、`@myriaddreamin/typst-ts-renderer` 和 `@myriaddreamin/typst-ts-web-compiler`;Typst 源文件编译、按页 SVG 渲染、缩放、打印和导出统一由 `@file-viewer/renderer-typst` 或 `@file-viewer/preset-all` 装配,core 直接运行时依赖从 8 降到 5,Phase 2 依赖预算从 7 降到 4
* CAD 预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `@flyfish-dev/cad-viewer`;DWG / DXF / DWF / DWFx / XPS 完整预览统一由 `@file-viewer/renderer-cad` 或 `@file-viewer/preset-all` 装配,core 直接运行时依赖从 5 降到 4,Phase 2 依赖预算从 4 降到 3
* Spreadsheet 预览从 core 兼容入口中彻底移出,新增 `@file-viewer/renderer-spreadsheet` 独立 renderer 包承接 XLSX / XLSM / XLSB / XLS / CSV / ODS / FODS / Numbers 等表格格式;`@file-viewer/core` 不再默认安装 `styled-exceljs`、`e-virt-table` 和 `tinycolor2`,完整表格能力统一由 `@file-viewer/renderer-spreadsheet` 或 `@file-viewer/preset-all` 装配,core 直接运行时依赖从 4 降到 1,Phase 2 依赖预算从 3 降到 0
* `.gds` 新增标准 GDSII 记录解析、SVG 版图预览和大元素集 WebGL canvas,能够展示 structure、boundary、path、text、reference、层信息和坐标边界;`.oas`、`.oasis` 文本夹具可生成 SVG 版图,真实 SEMI 二进制 OASIS 保持纯前端安全结构索引、可读字符串、实体候选、二进制线索和诊断,避免把专业 EDA 文件误当普通文本或空白二进制
* 邮件预览迁移为 `@file-viewer/renderer-email` 独立 renderer 包,继续支持 EML / MSG / MBOX、正文/头信息切换、附件下载和附件嵌套预览,并由 `@file-viewer/preset-all` 自动聚合
* OFD 预览迁移为 `@file-viewer/renderer-ofd` 独立 renderer 包,继续基于 `DLTech21/ofd.js` 的纯前端源码链路解析和页面渲染,vendor 随包离线分发,并由 `@file-viewer/preset-all` 与 `@file-viewer/vite-plugin` 自动聚合
* EPUB 预览迁移为 `@file-viewer/renderer-epub` 独立 renderer 包,继续使用 `epubjs` 提供目录、滚动阅读、章节跳转和阅读进度,并由 `@file-viewer/preset-all` 自动聚合
* 代码与 Markdown 预览迁移为 `@file-viewer/renderer-text` 独立 renderer 包,继续使用按语言动态加载的 `highlight.js` 和 `marked`,并由 `@file-viewer/preset-all` 自动聚合
* 图片预览迁移为 `@file-viewer/renderer-image` 独立 renderer 包,普通图片继续使用浏览器原生解码,HEIC / HEIF 只在命中格式时按需加载 `heic2any`,并由 `@file-viewer/preset-all` 自动聚合
* 音视频预览迁移为 `@file-viewer/renderer-media` 独立 renderer 包,MP4 / WebM / 常见音频继续使用原生控件,HLS 和 MIDI 只在命中格式时按需加载 `hls.js` / `@tonejs/midi`,并由 `@file-viewer/preset-all` 自动聚合
* 地理数据预览迁移为 `@file-viewer/renderer-geo` 独立 renderer 包,GeoJSON 直接读取,KML / GPX 按需加载 `@tmcw/togeojson`,SHP 按需加载 `shpjs`,地图叠加层和 CRS 转换按需加载 `maplibre-gl` / `proj4`,并由 `@file-viewer/preset-all` 自动聚合
* 新增 `@file-viewer/vite-plugin` 工程化入口,支持按 `formats` 自动生成 `virtual:file-viewer-renderers`、renderer chunk 分组、缺失 renderer 提示,并复制 PDF/CAD/Typst/Archive 离线 worker/WASM/vendor 资源和部署 manifest
* `@file-viewer/vite-plugin` 新增 `scan: true` 源码 hint 自动装配能力,可从 `fileViewerFormats` / `fileViewerRenderers` / `data-file-viewer-formats` / 上传 `accept` 声明提取格式并选择对应 renderer;新增 `verify:vite-plugin-auto-scan` 防止自动化装配链路回退
* 新增 `@file-viewer/preset-lite`、`@file-viewer/preset-office` 和 `@file-viewer/preset-engineering` 三个标准 preset 包;`@file-viewer/vite-plugin` 支持 `preset: 'lite' | 'office' | 'engineering' | 'all'`,会导入对应 `@file-viewer/preset-*` 包,并可继续用 `formats` 补充 preset 外 renderer,兼容 pnpm 严格依赖模型
* `verify:renderer-standalone-smoke` 从 PDF-only 升级为全独立 renderer plugin 门禁,使用本地 tarball 构造隔离业务项目,安装 core、Vite 插件、19 个 renderer plugin 以及本地依赖闭包,逐个验证 renderer 注册、handler 挂载、Vite selection 映射和 virtual module 不误引入无关 renderer 包
* 标准组件 README 与开源总仓 README 新增“工程级按需 renderer 装配”双语片段,统一说明 `@file-viewer/vite-plugin`、`virtual:file-viewer-renderers`、`builtinRenderers:'none'`、`rendererMode:'replace'`、`scan:true`、`copyAssets:true` 和 `@file-viewer/preset-all` 的推荐使用边界,并由 `verify:ecosystem-readmes` 纳入自动校验
* STEP / IGES / IFC / 3DM / BREP 等重型工程格式完成浏览器 WASM 路线调研,并新增 `@file-viewer/geometry-engine` 独立边界包维护签名识别、推荐内核和转换说明;OpenCascade、web-ifc、rhino3dm 等重 WASM 不进入 core 首屏链路
* 表格预览新增 `options.spreadsheet.resizableColumns` 开关,默认关闭以保持历史交互兼容;官方 Demo 默认开启,方便客户拖拽表头边界查看被截断的长文本
* Demo 新增 `mindmap.xmind`、`layout.gds`、`layout.oas`、`layout.oasis` 示例,并将样例选择器补充为脑图与绘图、邮件与 EDA 等更清晰分组
## `v2.0.11` Vanilla JS 原生组件增强版 [#v2011-vanilla-js-原生组件增强版]
* 全生态包版本同步推进到 `2.0.11`,Demo、官网、文档站、组件 README、开源总仓库和 npm 发布统一使用最新 Vanilla JS 入口
* `@file-viewer/web` 新增 `` 原生 Web Component,支持 `src/url`、`filename/name`、`type`、`size`、`theme`、`toolbar`、`toolbar-position`、`watermark`、`search`、`options` 等属性,并暴露完整 controller 实例方法
* IIFE script 标签包会自动注册 Custom Element,同时继续暴露 `window.FlyfishFileViewerWeb.mountViewer`,兼顾无构建工具页面和完全命令式接入场景
* 组件 Demo 新增 Custom Element 独立页面,并把浏览器 smoke 扩展到原生元素、IIFE 自动注册、React、Vue3、jQuery、Svelte 和手写 JS 入口
* 文档站、官网首页和 README 将纯 JS 默认推荐路径更新为 Web Component,`mountViewer` 作为高级 controller API 保留
## `v2.0.10` DOCX 自研渲染引擎稳定版 [#v2010-docx-自研渲染引擎稳定版]
* 全生态包版本同步推进到 `2.0.10`,Demo、组件 Demo、官网、文档站和开源总仓库统一使用当前 DOCX 主链路
* `@file-viewer/core` 继续使用自研 `@file-viewer/docx@0.3.12`,默认 Worker 解析、连续流式阅读、目录字段缓存、异步分批渲染和离线 `workerUrl` / `workerJsZipUrl` 资源配置
* DOCX 默认保持流式布局,避免复杂目录、长表格、制表符、样式继承和中文正式文档在视觉分页中被拆坏;需要页式效果的业务仍可显式开启 `options.docx.visualPagination`
* 开源 README、文档站、组件 README、Demo 样例与发布产物统一以当前 DOCX 能力为准,便于客户直接升级验证
## `v2.0.9` 生态文档与定制能力完善版本 [#v209-生态文档与定制能力完善版本]
* 文档站、README 和各生态组件 README 全量补齐实际支持的 props / options / events / controller API,覆盖 Vanilla JS / Pure Web、Vue3、Vue2.7、Vue2.6、React、React Legacy、jQuery、Svelte、core 与兼容 alias 包
* 工具栏定制能力文档化,统一说明 `options.toolbar`、`toolbar.beforeOperation`、`toolbar.items`、自定义按钮、隐藏默认工具栏和外部自定义工具栏的最佳实践
* 官网首页补充多框架快速接入代码切换板块,帮助用户在 Vanilla JS / Pure Web、Vue、React、Svelte、jQuery 和 core API 之间快速定位接入方式
* 生态发布口径同步刷新到 `2.0.9`,继续保持 core 纯 TypeScript 底座、各框架组件独立实现、离线资源随包分发和生产级 demo / 文档站 / 官网一体上线
## 当前主线 [#当前主线]
### 当前主线 DOCX 自研渲染引擎接入 [#当前主线-docx-自研渲染引擎接入]
* DOCX / DOCM / DOTX / DOTM 渲染切换为自研 `@file-viewer/docx`,默认启用 Worker ZIP/XML 解析、真实浏览器 DOM 连续流式渲染、目录字段缓存和异步分批渲染;页式预览改为 `options.docx.visualPagination: true` 显式开启
* 新增 `options.docx.workerJsZipUrl`,与 `options.docx.workerUrl` 一起支持完全离线部署;viewer assets 会复制 `vendor/docx/docx.worker.js` 和 `vendor/docx/jszip.min.js`
* `options.docx.worker` 默认开启,仅在 CSP 或宿主环境禁用 Worker 时需要关闭;默认超时提升到 120000ms,降低大文档误回退概率
* 文档站、README、格式矩阵和纯 JS 离线接入说明同步改为 `@file-viewer/docx` 口径
### 当前主线 生态接入文档全量对齐 [#当前主线-生态接入文档全量对齐]
* 新增 [生态组件总览](/zh/guide/ecosystem),集中说明 `@file-viewer/core`、`@file-viewer/pptx`、Vanilla JS / Pure Web、Vue3、Vue2.7、Vue2.6、React、React Legacy、jQuery、Svelte 和历史兼容包的选型边界
* 文档站导航、快速开始、Vue2/React/Pure Web 接入、组件用法、FAQ、发布分发和开发发版说明统一改为 `@file-viewer/*` 标准包名优先
* 补齐 Svelte 组件/action、jQuery 插件、Pure Web script 标签、Core 自定义接入、离线 viewer assets 和统一 controller API 示例
* 修正 React 文档中的事件参数为标准 `onEvent`,并明确 React Legacy、Vue2.6、PPTX 引擎和离线资源复制流程
### 当前主线 全格式浏览器冒烟与静态资源稳定性修复 [#当前主线-全格式浏览器冒烟与静态资源稳定性修复]
* 修复 3D 模型、OFD、EPUB、UMD、绘图和 CAD 等渲染器的隐藏 loading 状态在部分浏览器/CSS 组合下仍可见的问题,避免预览完成后继续显示“正在解析”
* Draw\.io 默认切换为随 viewer assets 分发的官方 diagrams.net 离线 viewer,加载超时后自动切换本地 SVG 安全预览,保证 `drawio` / `dio` 样例不会因 viewer 初始化卡住而长期 loading
* PDF 预览新增 `options.pdf.thumbnails`,页面导航可切换为真实页面缩略图;缩略图使用 IntersectionObserver 按可见区域懒渲染,避免大文档一次性生成所有 canvas
* PDF 视图会在页面初始化、缩放、旋转和渲染后写回传统 `px` 页面尺寸,兼容不支持 CSS `round()` 的 360 极速、华为浏览器等 Chromium 分支
* Typst compiler / renderer WASM 和默认字体资产改为随 viewer assets 本地分发,并新增 `options.typst.fontAssetsUrl` / `options.typst.renderTimeoutMs`;默认加载 / 编译超时提升到 180 秒,浏览器端始终走真实 SVG 预览链路,不再用源码视图冒充成功,也不再为默认字体访问公共 CDN
* Cloudflare Pages 部署脚本会对超过单文件限制的 Typst compiler WASM 自动做 Brotli 预压缩并写入 `_headers`,补齐 `Content-Encoding: br`、`Vary: Accept-Encoding`、WASM MIME 和长期缓存策略;新增 `pnpm verify:cloudflare-compression` 用于上线后验证官网、文档站、Demo 和 Typst WASM 的 Cloudflare 压缩响应
* 运行时不再提供公共 CDN 或第三方在线资源 fallback;Typst 本地 WASM 或字体目录不可用时会显示明确部署错误,Draw\.io 默认走官方离线 viewer 并在异常时回退内置 SVG,适合企业内网和纯离线部署
* PDF.js worker、CMap、WASM 和 standard fonts 默认随 viewer assets 分发到 `vendor/pdf/`,构建脚本会同步复制并校验,避免 PDF 预览隐式访问公网静态资源
* SQLite 预览默认使用 viewer assets 中的 `wasm/data/sql-wasm.wasm`,构建脚本同步复制并校验 sql.js WASM,减少移动端 WebView、本地服务器和 CSP 环境下的加载不确定性
* PDF 样式注入会去除 PDF.js 内置外部图片引用,避免静态产物部署时因 `images/shadow.png` / `loading-icon.gif` 缺失导致 404 或控制台噪声
* 新增全量 demo sample matrix 浏览器冒烟,逐一打开 `example/` 下 107 个样例文件;本轮已在 dev server 和静态 dist 产物中完成真实浏览器验证
### `v2.0.1` 架构重构与全生态 2.x 起始版本 [#v201-架构重构与全生态-2x-起始版本]
* 全线 npm 包、workspace 依赖、Docker 镜像和开源 release 包从 `2.0.1` 重新起步,用大版本号明确标识 core / component 架构重构带来的兼容边界变化
* `@file-viewer/core` 继续保持纯 TypeScript、框架无关的底层能力包;Vanilla JS / Pure Web、Vue3、Vue2.7、Vue2.6、React、React Legacy、jQuery、Svelte 等标准组件包只依赖 core,各自提供原生集成体验
* 清理旧独立页面实现和历史过渡口径,对外文档统一强调原生组件与纯 Web API 是核心集成路径
* 开源总仓库产物命名切换为 `file-viewer-v2-*`,同时发布 2.x npm tarball、Demo、Component Demo、文档站静态产物和库 dist 包,避免继续暴露旧 `file-viewer-v3-*` 产物线
* 文档、README、分发说明、Docker 部署说明和生态验收清单同步刷新到 2.x 版本口径,后续新增能力都在 2.x 线上连续演进
### 当前主线 统一缩放工具栏 [#当前主线-统一缩放工具栏]
* `options.toolbar.zoom` 新增统一缩放按钮显示控制,默认开启;按钮是否真正展示仍由当前渲染链路的内部缩放 provider 决定,避免对虚拟表格、canvas、PDF 文本层和 CAD 交互做宿主级 CSS 强缩放
* 组件 ref 新增 `zoomIn()`、`zoomOut()`、`resetZoom()` 和 `getZoomState()`,外部自定义工具栏可以通过标准 API 控制缩放;`operation-availability-change` 同步返回 `zoom`、`zoomIn`、`zoomOut` 和 `zoomReset`,`zoom-change` 回传最终比例文本
* PDF、DOCX、PPTX、Excel 虚拟表格、图片、CAD、OFD、Typst、Markdown、代码和 Excalidraw / draw\.io 绘图链路接入渲染器内部缩放逻辑;缩放操作同样进入 `options.beforeOperation` / `toolbar.beforeOperation` 前置校验
### `v1.0.26` Vue3 npm 入口类型声明修复版本 [#v1026-vue3-npm-入口类型声明修复版本]
* 修复 `@flyfish-group/file-viewer3@1.0.25` 在发布前被 Demo 构建覆盖 `dist` 后,npm 包缺少 `dist/src/package/index.d.ts`,导致 TypeScript 项目出现 `TS2307: Cannot find module '@flyfish-group/file-viewer3' or its corresponding type declarations` 的问题
* Vue3 标准组件包 使用包内 `prepublishOnly` 发布前保护,根包只保留 monorepo 编排脚本,阻止 Demo HTML 产物误进入组件库 npm 包
* 非 scoped 包 `file-viewer3` 同步发布 `1.0.26`,继续作为 `@flyfish-group/file-viewer3` 的兼容 alias 使用;开源总仓库只保留一份 scoped v3 tarball,避免重复占用存储
* 支持格式矩阵补齐到 194 个扩展名、23 条预览链路,新增 RTF/ODT/ODP、MBOX、GeoJSON/KML/GPX/SHP、AVIF/ICO/HEIC/HEIF/JXL、WEBM/M3U8、MIDI、JSONC/JSON5/IPYNB/TOML/Proto/HCL/TeX/Graphviz/HTTP/Ruby/Swift/Kotlin/React 片段,以及字体、PSD、AI/EPS、SQLite、WASM、Parquet、Avro、WebArchive 等资产/数据预览入口
### `v1.0.25` 移动端压缩包与表格体验修复版本 [#v1025-移动端压缩包与表格体验修复版本]
* Vue3 包 `@flyfish-group/file-viewer3@1.0.25`、Vue2 包 `@flyfish-group/file-viewer@1.0.25`、React 包 `@flyfish-group/file-viewer-react@1.0.25` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.25` 继续保持连续版本
* 压缩包预览迁移为 `@file-viewer/renderer-archive` 独立 renderer,并保留 Worker 探测、初始化超时、静态 Worker/WASM 路径和 ZIP/TAR/GZIP 兼容模式;手机 WebView、本地临时服务器、MIME 或 CSP 导致 `libarchive.js` Worker 卡住时,会自动降级,避免一直停留在 loading
* `options.archive` 新增 `wasmUrl` 和 `workerTimeoutMs` 说明;普通私有化部署不再需要写死 `workerUrl`,只有静态目录或 WASM 路径特殊时才需要显式指定
* 移动端 Excel / XLS 预览把工作表名称移到表格上方的横向可滚动标签栏,当前工作表自动滚入可见区域,解决手机上 sheet 名称藏在底部角落、需要技巧才能看到的问题
* Excel / XLS 多 sheet 场景下,工作表标签改为按内容宽度展示并横向滚动,避免按整体宽度平均压缩导致 sheet 名称完全看不清
* Excel / XLS 静态 Worker 改为显式 opt-in,默认使用同一套主线程解析器,避免本地服务器、手机 WebView、MIME 或 CSP 环境下停在 Worker 初始化阶段
* DOCX 默认采用真实浏览器 DOM 连续渲染;`docx.worker` 和 `docx.progressive` 保持默认开启以提升大文档响应,`docx.visualPagination` 改为显式 opt-in,避免复杂目录、长表格、制表符和样式继承被分页拆坏
* README、文档站、React / 纯 JS 接入文档、开源 release 包和 workspace 依赖同步刷新到 `1.0.25`
### 当前主线 Demo 富样式公开样例升级 [#当前主线-demo-富样式公开样例升级]
* DOCX 渲染链路下沉到 `@file-viewer/core`,移除 Vue3 本地 Word vendor 入口;所有标准组件包共享同一套 DOCX 页面渲染、缩放 provider、打印和 HTML 导出适配器
* DOCX Worker 保留 `options.docx.workerUrl`、`options.docx.workerJsZipUrl` 与 `options.docx.workerTimeout` 兜底,静态资源不可用、CSP/MIME 不兼容或超时后由 DOCX 引擎自动回退
* CAD 渲染器保持在 `@flyfish-dev/cad-viewer` 0.6.4,支持 DWG / DXF / DWF / DWFx / XPS 统一预览;DWG 默认通过独立 Worker 加载 LibreDWG WASM,DWF/DWFx/XPS 使用 native renderer 渲染 W2D/W3D/XPS 图形
* 构建脚本会复制 `libredwg-web.js`、`libredwg-web.wasm`、`dwfv-render.wasm`、`dwg-worker.js` 和 worker 依赖 chunk 到 viewer assets 的 `wasm/cad/`
* Demo 补充 Apache Tika `blocks_and_tables.dwf` 与 Autodesk 官方 Viewer 教程的 `House.dwfx`、`RobotArm1.dwfx` 样例,用于分别验证 DWF、DWFx/XPS、W2D/W3D native renderer 和大图纸按需加载体验
* 入口组件在挂载重型渲染器前先释放浏览器绘制帧,确保 Loading 先显示,减少用户误以为页面无响应
* `word.docx` 保持 Basel Convention 公开中文正式文档,覆盖长正文、标题层级、表格、图示、白色纸张和完整打印回归,避免默认 Demo 使用临时生成或过度病态的样例文件
* `ppt.pptx` 与英文 `sample-presentation.pptx` 替换为 NASA Science 公开月球科学战略演示稿,覆盖星云封面、深色引用页、图文混排、正式页眉页脚和 20 页真实专业 PPTX 结构
* `archive.zip` 与 `archive.tar.gz` 内部 DOCX 同步更新为当前公开中文 Word 样例,压缩包内继续预览时也能验证真实文档效果
* 示例来源表、Demo 文档和公开样例 README 同步刷新,避免继续把 Word / PPT 误写成临时生成的 Demo 文件
### 当前主线 文档比对、搜索定位和 AI 友好结构增强 [#当前主线-文档比对搜索定位和-ai-友好结构增强]
* 文档比对页同步滚动改为绑定真实预览滚动容器,并按 scroll ratio 同步左右滚动位置,PDF 内部滚动层、Word 外层滚动层和文本预览都走同一套逻辑
* 文档比对页搜索改为当前聚焦文档的浮层交互,配合成熟图标按钮提供关键词搜索、高亮命中、上一个 / 下一个;避免顶部工具区拥挤,也避免左右两侧同时滚动导致视线丢失
* 文档比对页继续提供行级定位;搜索、定位和文本切片结果会返回行号、页码和锚点上下文,便于业务侧做审计与溯源
* 新增 `options.pdf.toolbar`,可在左右比对等紧凑场景隐藏 PDF 自身页码、缩放、旋转工具栏,避免 PDF 比其他格式多一条顶部导航导致正文错位
* 新增 `options.search`、`searchDocument()`、`clearDocumentSearch()`、`nextSearchResult()`、`previousSearchResult()`、`getSearchState()` 等通用搜索 API;PDF 等特殊渲染器可注册原生搜索提供器,避免通用 DOM 高亮污染文本层或 canvas
* 新增 `collectDocumentAnchors()`、`scrollToLine()`、`scrollToAnchor()` 和 `getDocumentTextChunks()`,预览器只提供锚点、文本切片和溯源上下文,不绑定具体 AI 服务,业务侧可基于它做向量化、召回、高亮和来源定位
* 主 Demo 和文档比对 Demo 的搜索浮层统一改用成熟图标按钮,公开文档同步补充文档比对页、搜索定位、PDF 工具栏隐藏、AI 友好结构和溯源定位说明
### `v1.0.24` CAD native renderer 与构建产物同步版本 [#v1024-cad-native-renderer-与构建产物同步版本]
* Vue3 包 `@flyfish-group/file-viewer3@1.0.24`、Vue2 包 `@flyfish-group/file-viewer@1.0.24`、React 包 `@flyfish-group/file-viewer-react@1.0.24` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.24` 继续保持连续版本
* CAD 渲染器升级到 `@flyfish-dev/cad-viewer@0.6.2`,DWG / DXF / DWF / DWFx / XPS 统一走成熟 CAD viewer;DWF/DWFx/XPS 使用 `dwf-viewer@0.6.4` native renderer 解析 W2D/W3D/XPS 图形
* 构建脚本新增复制 `dwfv-render.wasm`,与 `libredwg-web.js`、`libredwg-web.wasm`、`dwg-worker.js` 和 worker 依赖 chunk 一起进入 `wasm/cad/`,私有化部署可通过 `options.cad.dwfWasmUrl` 覆盖路径
* 压缩包和邮件附件的嵌套预览同步识别 `dwf`、`dwfx`、`xps`,避免主入口支持 CAD 五类格式而附件链路覆盖不足
* Demo 图纸分组补充 Apache Tika `blocks_and_tables.dwf` 以及 Autodesk 官方 Viewer 教程的 `House.dwfx`、`RobotArm1.dwfx` 样例,便于验证 DWF、DWFx/XPS、多页结构、W2D/W3D 图形、视图适配和按需加载体验
* README、文档站、React / 纯 JS README、入口缓存策略、开源 release 包和 workspace 依赖同步刷新到 `1.0.24`
### `v1.0.22` PPTX 兼容性修复与连续发布版本 [#v1022-pptx-兼容性修复与连续发布版本]
* Vue3 包 `@flyfish-group/file-viewer3@1.0.22`、Vue2 包 `@flyfish-group/file-viewer@1.0.22`、React 包 `@flyfish-group/file-viewer-react@1.0.22` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.22` 继续保持连续版本
* 修复部分客户 PPTX 无法打开的问题,兼容缺少 `docProps/app.xml` 的演示文稿,默认按现代 Office 版本降级解析
* PPTX OpenXML 关系解析改为通用路径解析,支持 relationship 单对象 / 数组 / 缺失三种形态,并按 `presentation.xml` 真实 slide 顺序渲染
* 增强 slide / layout / master / theme / diagram 关系读取容错,缺失可选部件时降级渲染当前页内容,不再因空指针导致整份 PPTX 白屏
* README、文档站、React / 纯 JS README、入口缓存策略、开源 release 包和 workspace 依赖同步刷新到 `1.0.22`
### `v1.0.21` Docker Hub 仓库与格式边界校准版本 [#v1021-docker-hub-仓库与格式边界校准版本]
* Vue3 包 `@flyfish-group/file-viewer3@1.0.21`、Vue2 包 `@flyfish-group/file-viewer@1.0.21`、React 包 `@flyfish-group/file-viewer-react@1.0.21` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.21` 继续保持连续版本
* 清理 `.wps`、`.wpt`、`.et`、`.ett`、`.dps`、`.dpt` 等当前没有开箱即用浏览器渲染方案的 WPS 原生格式说明,避免用户误以为这些格式已经完整支持
* Office 模板和宏格式继续按实际可渲染链路保留,包括 `dot`、`dotx`、`dotm`、`docm`、`xlt`、`xltx`、`xltm`、`pptm`、`potx`、`potm`、`ppsx`、`ppsm`
* 新增 Docker Hub 仓库创建脚本,支持用 Docker Hub API 创建 `flyfishdev/file-viewer` 公开仓库,并在异常时输出更明确的安全诊断信息
* 文档站补全文档比对页使用说明,明确 `/compare.html`、`left` / `right` 预置参数、内置示例、URL、本地上传、同步滚动、私有化部署路径和视觉比对边界
* 开源总仓库新增 Gitee 镜像 `gitee.com/flyfish-dev/file-viewer`,GitHub / Gitee 同步交付混淆构建产物、Demo、文档静态产物、示例文件和 tarball
* Demo 输出校验继续覆盖 `compare.html`、主入口资源、viewer 资源目录和示例资源,避免上线缺少独立比对入口
* 文档站新增 Cloudflare Pages Direct Upload 脚本和 `docs/public/_headers` 缓存策略,`doc.file-viewer.app` 可切换到 `flyfish-file-viewer-docs.pages.dev` 以改善国内访问速度
* 新增 `options.theme`,支持 `light`、`dark`、`system`;显式主题优先于浏览器 `prefers-color-scheme`,固定浅色业务 UI 可以传 `light` 避免 Markdown、代码、Typst 等预览区域被系统暗色模式带偏
* 新增 `toolbar.position`,支持 `auto`、`top`、`bottom-right`;默认 `auto` 下 PDF 通用下载/打印/HTML 操作栏会悬浮到右下角,避免和 PDF 页码、缩放、目录导航栏形成双顶部导航
* 升级 Vue、Vite、PDF.js、Axios、Marked、React 适配层等第三方依赖到当时 npm latest,并同步刷新 DOCX 构建 chunk
* DOCX 渲染关闭生产调试告警,兼容 Word 写入的 `autoSpaceDN` / `autoSpaceDE` 等段落属性,避免控制台被 `DOCX: Unknown document element` warning 刷屏
* README、文档站、React / 纯 JS README、入口缓存策略和 workspace 依赖同步刷新到 `1.0.21`
### `v1.0.20` Typst 直读源文件与边缘部署优化版本 [#v1020-typst-直读源文件与边缘部署优化版本]
* Vue3 包 `@flyfish-group/file-viewer3@1.0.20`、Vue2 包 `@flyfish-group/file-viewer@1.0.20`、React 包 `@flyfish-group/file-viewer-react@1.0.20` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.20` 统一推进到连续版本
* Typst 严格直读 `.typ` / `.typst` 源文件并以轻量代码视图展示,禁止依赖 sidecar 或预编译 PDF,保证用户上传源码后即可直接查看
* PDF 远端 URL 加载链路新增渐进读取策略: 同源 PDF 默认直接交给 PDF.js 通过 URL 读取,服务端支持 Range 时自动分片加载,避免先整包下载 Blob 后才开始建页;跨域 URL 默认保持旧的兼容下载链路
* 新增 `options.pdf.streaming`、`options.pdf.rangeChunkSize` 和 `options.pdf.withCredentials`,可按业务文件服务能力控制 PDF 渐进读取、Range 分片大小和凭据策略
* 下载按钮支持 URL 源文件回退,流式 PDF 没有预下载 buffer 时也可以触发原始文件下载
* 新增 Cloudflare Pages Direct Upload 部署脚本、`wrangler.toml` 和 `_headers` 缓存策略,便于将 Demo 切到 Cloudflare 边缘网络并保持 `demo.file-viewer.app` 域名不变
* 新增独立文档比对入口 `/compare.html`,支持左右并排预览、示例选择、URL、本地上传和同步滚动,不污染主预览入口
* 新增 Dockerfile、nginx 静态运行配置和 buildx 发布脚本,发布镜像覆盖 `linux/amd64` 与 `linux/arm64`,用于一键部署 Demo 与比对页
* 新增 Office 模板兼容入口,覆盖 `dot`、`dotx`、`dotm`、`docm`、`xlt`、`xltx`、`xltm`、`pptm`、`potx`、`potm`、`ppsx`、`ppsm`
### `v1.0.19` 页面尺寸感知打印与入口组件瘦身版本 [#v1019-页面尺寸感知打印与入口组件瘦身版本]
* Vue3 包 `@flyfish-group/file-viewer3@1.0.19`、Vue2 包 `@flyfish-group/file-viewer@1.0.19`、React 包 `@flyfish-group/file-viewer-react@1.0.19` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.19` 统一推进到连续版本
* PDF 打印会按真实页面 CSS 尺寸生成完整高保真页图,并通过 `@page size` 固定输出纸张大小,避免导航窗格、视口宽度或缩放状态导致页面被挤压、裁切或只打印当前页
* DOCX / DOC 打印保留白色纸张和文档页尺寸,导出窗口只包含主体页面,避免把 Demo 外壳、工具栏、滚动容器或预览缩放带入打印结果
* 新增 `printStyle` 渲染适配器能力,PDF、DOCX、DOC 等有真实页面尺寸的格式可以按文件自身尺寸输出打印样式,后续格式可复用同一机制
* 将下载、打印、导出 HTML 的实现从 `FileViewer.vue` 抽离到 `useViewerExport` 和导出模板 helper,入口组件回归预览状态、生命周期和操作可用性的单一职责
* 补充打印页尺寸与导出模板单测,并同步刷新文档站、README、Demo 示例版本、开源 release 包和 npm 版本说明到 `1.0.19`
### `v1.0.18` 公开 issue 修复与真实 PDF 示例版本 [#v1018-公开-issue-修复与真实-pdf-示例版本]
* Vue3 包 `@flyfish-group/file-viewer3@1.0.18`、Vue2 包 `@flyfish-group/file-viewer@1.0.18`、React 包 `@flyfish-group/file-viewer-react@1.0.18` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.18` 统一推进到连续版本
* 修复 GitHub issue #13: PDF 旋转页与导航配置兼容性增强,新增 `options.pdf.navigation` 和 `options.pdf.defaultNavigationVisible`,继续保持页侧边栏 / 树形目录侧边栏切换
* 修复 GitHub issue #9 与 #8: Excel 自动文本色更可靠,支持 workbook drawing 图片渲染,并按渲染链路隐藏不可靠的打印 / 导出入口
* 修复 GitHub issue #4: `.doc` 表格布局和单元格可读性增强,老 Word 文档在白色纸张容器里更接近实际阅读效果
* 修复 GitHub issue #1: `.doc` 的 `msdoc-viewer` CFB 局部 sector 容错改为包管理器无关的 `scripts/patch-msdoc-viewer.mjs`,npm / pnpm / yarn 安装后都可在构建前自动应用
* Demo PDF 替换为项目方提供的 13 页《PDF沉浸式翻译技术说明》,用于验证长文档阅读、缩放、页导航、树形目录、完整打印和 HTML 导出
* 文档站、README、集成说明、示例来源、开源 release 包和 npm 版本说明同步刷新到 `1.0.18`
### `v1.0.17` 打印能力矩阵与完整页打印版本 [#v1017-打印能力矩阵与完整页打印版本]
* Vue3 包 `@flyfish-group/file-viewer3@1.0.17`、Vue2 包 `@flyfish-group/file-viewer@1.0.17`、React 包 `@flyfish-group/file-viewer-react@1.0.17` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.17` 统一推进到连续版本
* PDF 导航窗格继续完善“页面 / 目录”切换,目录模式支持树形层级、展开折叠和定位跳转,便于用户在长文档中快速预览
* Word、DOC 和 PDF 预览统一增强打印 / HTML 导出,专属导出适配器会移除预览缩放、滚动容器和 Demo 全局布局样式,避免只打印一页或页面被截断
* 新增打印能力动态判断,表格、压缩包、邮件、EPUB、音视频、3D 等不适合直接打印的渲染链路会自动隐藏打印按钮,避免用户进入错误打印流程
* 优化 Demo 暗色模式和 Markdown 阅读面,Markdown / 代码跟随系统主题,PDF / Word / Excel 等原始版式内容保持独立显示;同时替换更丰富的 DOCX / PDF / Markdown 示例并同步压缩包样例
* 新增文档加载、卸载生命周期钩子,以及下载、打印、导出 HTML 的按钮前置校验钩子,历史适配层同步透出事件和操作能力变化
* 文档站、README、集成说明、分发说明和开源 release 包说明同步刷新到 `1.0.17`
### `v1.0.15` 预览交互、打印与集成钩子增强版本 [#v1015-预览交互打印与集成钩子增强版本]
* PDF 导航窗格新增“页面 / 目录”切换,目录模式会读取 PDF 大纲并以可展开树形结构跳转,页面模式继续保留页侧边栏
* 增强 Word 和通用文档打印导出,`.docx` / `.doc` 会使用专属导出适配器清理预览缩放、绝对定位和滚动容器,避免只打印一页或页面被截断
* 新增 `options.hooks` 生命周期钩子,覆盖文档开始加载、加载完成、开始卸载和卸载完成,并提供文件类型、文件名、来源、URL、大小、版本和耗时上下文
* 新增 `options.beforeOperation` 与 toolbar 级前置操作钩子,下载、打印、导出 HTML 前都可以返回 `false` 取消,便于接入权限校验、审计确认和业务二次弹窗
* React / 纯 JS 适配层新增 viewer 事件监听入口,基线预览器会向宿主同步生命周期和操作事件
* 文档、README 和四条 npm 包线版本说明同步刷新到 `1.0.15`
### `v1.0.14` 最新发布与文档站同步版本 [#v1014-最新发布与文档站同步版本]
* Vue3 包 `@flyfish-group/file-viewer3@1.0.14`、Vue2 包 `@flyfish-group/file-viewer@1.0.14`、React 包 `@flyfish-group/file-viewer-react@1.0.14` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.14` 统一抬升到最新版本
* 文档站首页、快速开始、分发说明、支持格式页和 README 中的安装示例同步刷新到 `1.0.14`
* 开源总仓库、Demo 静态产物和文档站静态产物重新构建,方便直接下载和验收
* 继续保持 Vue3 / Vue2 / React / 纯 JS 的集成路径、按需异步加载、示例分组和 PDF / OFD / 压缩包 / 邮件 / CAD / 绘图 / 电子书预览链路一致
### `v1.0.12` 完整格式、分发仓库与 npm 同步版本 [#v1012-完整格式分发仓库与-npm-同步版本]
* Vue3 包 `@flyfish-group/file-viewer3@1.0.12`、Vue2 包 `@flyfish-group/file-viewer@1.0.12`、React 包 `@flyfish-group/file-viewer-react@1.0.12` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.12` 统一对齐到 npm `latest`
* 新增压缩包预览,基于 `libarchive.js` Worker 支持 ZIP、7z、RAR、TAR、GZIP、BZIP2、XZ、CAB、ISO、JAR、APK、CBZ/CBR 等入口,内部文件按需解压、IndexedDB 缓存并继续调用统一预览器
* 新增 EML / MSG 邮件预览,支持头信息、HTML/文本正文、附件下载和附件继续在线预览
* 增强 OLB / DRA 结构预览,基于 `cfb` 解析常见 EDA 复合文档容器,并提供结构树、元件/封装/Padstack 候选、属性、诊断、二进制退化和可读字符串索引
* 预览器新增 `options.watermark`、`options.toolbar` 和 `options.archive`,支持文字/图片水印、下载原文件、完整打印、导出渲染后 HTML、压缩包 worker 和体积限制配置
* 修复 PDF 打印和导出 HTML 的完整性,PDF 会通过专属导出适配器逐页生成全部页面,不再依赖当前滚动视口、当前页或已渲染 canvas,避免只打印当前页或内容被截断
* DWG 入口从单纯提示转换为尽力展示: 误命名 DXF 会直接按 DXF 解析,真实 DWG 会尝试提取内嵌 PNG/JPEG/BMP 预览图,并说明无法完整解析几何的原因
* 新增 Three.js 3D 模型预览器,支持 `glb`、`gltf`、`obj`、`stl`、`ply`、`fbx`、`dae`、`3ds`、`3mf`、`amf`、`usd`、`usda`、`usdc`、`usdz`、`kmz`、`pcd`、`wrl`、`vrml`、`xyz`、`vtk`、`vtp`;`step`、`stp`、`iges`、`igs`、`ifc`、`3dm` 会给出转换原因和建议
* Demo 新增 GLTF / OBJ / STL / PLY / STEP 3D 样例,以及 ZIP、TAR.GZ、EML、MSG、OLB、DRA 样例,支持格式矩阵更新到 135 个扩展名、19 条预览链路
* 文档站全局导航、首页、格式矩阵、分发说明、快速开始和 npm README 均刷新到 `1.0.12`
* 开源总仓库已升级为一站式主入口,保留可运行源码、Demo 静态站、文档静态站、样例文件和 release tarball
* React / 纯 JS 文档继续推荐 `npm install` 零步骤安装,并补充 pnpm 10 拦截 `postinstall` 时的 `pnpm approve-builds` / `pnpm exec file-viewer-copy-assets` 处理方式
### `v1.0.9` 媒体、绘图与电子书预览增强版本 [#v109-媒体绘图与电子书预览增强版本]
* Vue3 包 `@flyfish-group/file-viewer3@1.0.9` 和 Vue2 包 `@flyfish-group/file-viewer@1.0.9` 同步发布到 npm `latest`
* 新增 React 包 `@flyfish-group/file-viewer-react@1.0.9` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.9`,复用 Vue3 基线资源
* 新增原生 组件 Demo,覆盖 React 组件和纯 JS helper 两种入口,构建后可直接作为私有化静态站点部署
* 增强 PPTX 渲染,补齐组合图形坐标映射、旋转/翻转、主题背景、图片裁剪和 EMF 转 SVG 预览
* 新增 `.epub` 预览,使用 `epubjs` 按需解析 EPUB 包、目录和滚动阅读,并避开部分浏览器超宽分页白板问题
* 新增 `.umd` 电子书预览,按 UMD 文件结构解析元数据、章节目录和 zlib 压缩正文
* 新增 `.mp3`、`.mpeg`、`.wav`、`.ogg`、`.oga`、`.opus`、`.m4a`、`.aac`、`.flac`、`.weba` 音频入口,使用浏览器原生播放器
* 新增 `.excalidraw` 预览,默认使用 rough.js 按需生成只读 SVG,运行环境提供官方 Excalidraw ESM 模块时可优先尝试 `exportToSvg`
* 新增 `.drawio` / `.dio` 预览,默认使用随 viewer assets 分发的官方 diagrams.net `GraphViewer` 离线处理 mxGraphModel / mxfile;也可通过 `options.drawing.viewerScriptUrl` 覆盖自托管脚本,异常时回退内置 SVG
* 补充 Demo 示例文件、格式矩阵、FAQ 和接入说明
### `v1.0.8` 文档视觉与预览稳定性版本 [#v108-文档视觉与预览稳定性版本]
* Vue3 包 `@flyfish-group/file-viewer3@1.0.8` 和 Vue2 包 `@flyfish-group/file-viewer@1.0.8` 同步发布到 npm `latest`
* 修复 PDF worker 生命周期,快速切换 PDF / OFD / PDF 时不再触发 worker 销毁告警
* 稳定 OFD 渲染状态,避免反复闪动“正在解析 OFD”
* 刷新文档站截图、主题配色和集成示例页视觉
### `v1.0.7` PDF 自适应修复版本 [#v107-pdf-自适应修复版本]
* Vue3 包 `@flyfish-group/file-viewer3@1.0.7` 和 Vue2 包 `@flyfish-group/file-viewer@1.0.7` 同步发布到 npm `latest`
* 修复 PDF.js 5 下 canvas 布局尺寸被 DPR backing store 干扰的问题,避免 PDF 页面被裁切或显示不完整
* 修复 PDF 默认宽度适配计算,导航窗格开启时也能按当前视口宽度给出可读缩放比例
* 同步刷新线上 Demo、文档说明和开源总仓库产物
### `v1.0.6` 开源分发版本 [#v106-开源分发版本]
* Vue3 包 `@flyfish-group/file-viewer3@1.0.6` 和 Vue2 包 `@flyfish-group/file-viewer@1.0.6` 均已发布到 npm `latest`
* 新增 PDF 缩放工具栏、页码状态和可显隐页面导航窗格
* 补齐 OFD、CAD、代码高亮与完整示例文件盒子
* 示例文件选择器支持分组折叠,默认展开第一个分组,并保持同一时间只展开一个分组
* 增加 `pnpm obfuscate` 与 `pnpm release:ecosystem:pack`,库产物支持压缩混淆后分发
* README、文档站和开源总仓库说明同步补充 npm、GitHub、私有聚合仓、优先支持、授权与贡献说明
* npm tarball 只包含 `README.md`、`LICENSE` 和混淆压缩后的 `dist/`
### 文档站与交付说明完善 [#文档站与交付说明完善]
* 重写 README 与旧版文档结构
* 增加 Demo 说明、本地开发与打包说明
* 补充截图、接入建议与发布前检查清单
### `.doc` 渲染能力升级 [#doc-渲染能力升级]
* 使用 `msdoc-viewer` 替换旧的 `.doc` 解析方案
* 将 `.doc` 内容渲染在 Word 风格页面容器中
* 增加灰色工作台、白色纸张与页面居中展示效果
### 示例与工程体验 [#示例与工程体验]
* 提供更清晰的本地 Demo 入口说明
* 支持将预览器独立部署并通过静态入口集成
* 本地构建、文档站构建与 npm 打包链路持续收敛
## 历史版本 [#历史版本]
### `v1.0.3` [#v103]
* 修复与优化 PDF 字体、缩放和 Excel 样式相关问题
### 更早版本 [#更早版本]
* 优化 PPTX 加载性能
* 补强 Word 与 Excel 的基础预览能力
* 持续完善 TypeScript 与 Vue 3 版本实现