Skip to content

Browser Preview ​

Render .docx files directly in the browser — no server, no file upload, no conversion step.

@docxkit/renderer brings Microsoft Word documents to the web using docx-preview (DOM-based, pixel-faithful) with an optional Microsoft Office Online iframe fallback.


Install ​

sh
npm install @docxkit/renderer

docx-preview (Apache-2.0, ~47 kB gzipped) and jszip are installed automatically.


Quick Start ​

ts
import { createDocxPreview } from '@docxkit/renderer'

const preview = createDocxPreview(
  document.getElementById('preview')!,
)

// Render a Blob (e.g. from docx-kit's toBlob())
await preview.render(blob)

// Later — clean up
preview.destroy()

Input Types ​

preview.render(input) auto-detects the input type:

TypeExampleNotes
Blobawait doc.toBlob()Most common — from DocxBuilder.toBlob()
FilefileInput.files[0]!From <input type="file">
ArrayBufferawait blob.arrayBuffer()From fetch() response
Uint8Arraynew Uint8Array(buffer)For binary data sources
string (URL)'https://example.com/doc.docx'Fetched via fetch()
ts
// Blob — from docx-kit
const doc = createDocx(/* ... */)
const blob = await doc.toBlob()
await preview.render(blob)

// File — from <input type="file">
const file = document.querySelector('input[type="file"]')!.files[0]!
await preview.render(file)

// URL — fetch from a server
await preview.render('https://example.com/report.docx')

Renderer Modes ​

DOM Renderer (default) ​

Uses docx-preview to render the DOCX as styled HTML elements inside the container.

Embedded HTML (altChunk) is disabled by default. Set renderAltChunks: true to display it in sandboxed iframes without script or same-origin permissions. Executable hyperlink schemes such as javascript: are removed. Embedded HTML may still request external resources, so leave it disabled for untrusted documents that must not contact external servers.

Each DOM render has an independent CSS scope and namespaced embedded fonts. Generated styles are parsed before mounting, and positioned content stays inside a containment wrapper. This wrapper is always present, including with inWrapper: false; that option controls only the decorative docx-preview wrapper. Existing class names and container.querySelector() access remain available.

  • Text is selectable and searchable (DOM-based)
  • Supports headers/footers, page breaks, tables, images
  • Fidelity: high (pixel-faithful to Word layout)
ts
const preview = createDocxPreview(container, {
  renderer: 'dom',  // default
  pageMode: 'paged',  // or 'continuous'
})

Microsoft Office Online (iframe fallback) ​

Embeds Microsoft's free online viewer via an <iframe>.

  • Requires a publicly accessible URL (Microsoft's servers must be able to fetch the file)
  • 100% fidelity (Microsoft's own renderer)
  • No programmatic control
ts
const preview = createDocxPreview(container, {
  renderer: 'microsoft',
})

// Only URL strings are supported
await preview.render('https://example.com/public/doc.docx')

For non-URL inputs, the Microsoft renderer throws with a clear error:

[MICROSOFT_URL_REQUIRED]
Microsoft renderer requires a publicly accessible URL string.
Received Blob. Upload the DOCX to a public URL first,
or use renderer: 'dom'.

Pagination ​

Paged Mode (default) ​

Each page rendered as a discrete white box with shadow — looks like a real document.

ts
const preview = createDocxPreview(container, {
  pageMode: 'paged',  // default
})

Continuous Mode ​

Single scrolling document, no page breaks.

ts
const preview = createDocxPreview(container, {
  pageMode: 'continuous',
})

API Reference ​

createDocxPreview(container, options?) ​

Creates a preview instance bound to a DOM container.

Parameters:

  • container: HTMLElement — The target DOM element
  • options: DocxPreviewOptions — Optional configuration

Returns: DocxPreview


DocxPreview Instance ​

MethodDescription
render(input)Render a DOCX input (Blob/File/ArrayBuffer/Uint8Array/URL)
clear()Remove rendered content and release its media URLs, keep instance alive
destroy()Full cleanup (revokes URLs, clears DOM, marks destroyed)
PropertyTypeDescription
containerreadonly HTMLElementThe bound container element
currentInputreadonly DocxInput | nullMost recently rendered input
ts
const preview = createDocxPreview(container)

// Render
await preview.render(blob)

// Re-render (replaces previous content)
await preview.render(anotherBlob)

// Clear without destroying
preview.clear()

// Full cleanup
preview.destroy()
// preview.render(...)  ← throws "has been destroyed"

Options ​

All options from docx-preview can be passed through:

OptionTypeDefaultDescription
renderer'dom' | 'microsoft''dom'Rendering backend
pageMode'paged' | 'continuous''paged'Page display mode
classNamestring'docx-kit-preview'CSS class on container
inWrapperbooleantrueAdd wrapper <div> around pages
breakPagesbooleantruePage breaks (overrides pageMode)
renderHeadersbooleanfalseRender page headers
renderFootersbooleanfalseRender page footers
renderFootnotesbooleanfalseRender footnotes
renderEndnotesbooleanfalseRender endnotes
ignoreFontsbooleanfalseDon't load web fonts
useBase64URLbooleanfalseUse base64 images (vs ObjectURL)
renderAltChunksbooleanfalseRender embedded HTML in inert sandboxed iframes
microsoftViewerUrlstringOffice Online URLCustom OOS server

Error Handling ​

All errors are DocxKitError instances with a structured code:

ts
import { createDocxPreview, PREVIEW_ERROR_CODES } from '@docxkit/renderer'
import { DocxKitError } from '@docxkit/core'

try {
  await preview.render(invalidInput)
} catch (err) {
  if (err instanceof DocxKitError) {
    switch (err.code) {
      case PREVIEW_ERROR_CODES.PREVIEW_INPUT_INVALID:
        console.error('Invalid input type:', err.message)
        break
      case PREVIEW_ERROR_CODES.PREVIEW_FETCH_FAILED:
        console.error('Network error:', err.message)
        break
      case PREVIEW_ERROR_CODES.PREVIEW_RENDER_FAILED:
        console.error('Render failed:', err.message)
        break
      case PREVIEW_ERROR_CODES.MICROSOFT_URL_REQUIRED:
        console.error('Microsoft mode needs URL:', err.message)
        break
    }
  }
}
CodeTrigger
PREVIEW_INPUT_INVALIDInput is null, undefined, or unrecognized type
PREVIEW_FETCH_FAILEDfetch() to URL failed (network or HTTP error)
PREVIEW_RENDER_FAILEDDOCX parsing or DOM rendering failed
MICROSOFT_URL_REQUIREDMicrosoft renderer called with non-URL input

Limitations ​

  • Browser-only — The renderer uses DOM APIs; it cannot run in Node.js
  • docx-preview limitations — very large documents (200+ pages) may be slow; track changes and comments rendering is experimental
  • Microsoft mode — requires a publicly accessible URL; documents are sent to Microsoft's servers
  • CJK fonts — supported if the user's system has the fonts installed; docx-preview inherits browser font handling

See Also ​

Released under the MIT License.