Word documents laid out as pages with docx-preview, isolated in a shadow root and sanitised
Tags: viewer word docx document
DocxViewer lays out .docx files as pages using docx-preview (opens in new tab). The document renders inside a shadow root, so its styles cannot affect your app and your app's styles cannot affect it.
Import
<script>
import { DocxViewer } from '@classic-homes/viewer-svelte/docx';
</script>Setup
npm install @classic-homes/viewer-svelte docx-previewNo configuration is needed.
Basic Usage
<script lang="ts">
import { loadSource } from '@classic-homes/viewer-svelte';
import { DocxViewer } from '@classic-homes/viewer-svelte/docx';
</script>
{#await loadSource('/specs/lot-12.docx') then source}
<DocxViewer {source} kind="docx" class="h-[80vh]" />
{/await}Props
| Prop | Type | Default | Description |
|---|---|---|---|
source |
LoadedSource |
required | Loaded bytes plus name and MIME hints |
kind |
RenderableKind |
required | 'docx' |
initialZoom |
ZoomMode |
'fit-width' |
'fit-width' (never above 100%), 'fit-page' or a scale |
hideToolbar |
boolean |
false |
Hide the toolbar |
onready |
() => void |
- | The document is on screen |
onerror |
(error: ViewerError) => void |
- | The document could not be read |
class |
string |
- | Classes for the outer element |
What it shows
Headers, footers, footnotes, endnotes, tables, images, lists and fonts embedded in the document. Pages break at explicit page breaks and at the breaks Word saved, so long passages without either can run longer than the printed page. Tables of contents and other fields show the values Word last saved.
It does not show tracked changes, comments or embedded HTML (altChunk). Find, zoom, page navigation, print and download all work, and links to bookmarks scroll within the viewer.
Security
docx-preview's output is treated as untrusted: embedded HTML is switched off (it would run as a same-origin frame), the archive is re-packed through size-checked inflation first, and the document renders into detached elements. Before anything is attached to the page, links go through the URL allow-list, resources are limited to the document's own images and fonts, and CSS @import and remote url() references are removed, so a crafted style or font name cannot make the browser fetch a stylesheet. Every object URL made for a render is revoked when it is replaced, cancelled or fails.
As defence in depth, serve pages that show untrusted documents with a Content Security Policy that limits where styles, images and fonts may load from. docx-preview writes inline <style> elements and style attributes, so style-src needs 'unsafe-inline'; the point is that it lists no remote origins, so even a stylesheet @import that slipped through would be blocked:
style-src 'self' 'unsafe-inline';
img-src 'self' blob: data:;
font-src 'self' blob: data:;Add your own origins (CDNs, API hosts) as needed.
Related
- DocumentViewer: detects the format and loads the right viewer
- PdfViewer: PDF pages