Skip to main content

DocxViewer

DocxViewer

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

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

On this page