# Embed a DOCX editor

Start with the public sample, then replace the document URL with a file your application is authorized to load. Uploaded files and shared room contents are never included in this project.

## Run

Requires Node.js 22 or newer. `npm install` then `npm run dev`. Open the localhost URL Vite prints. To check and build the project, run `npm run check` and `npm run build`.

Browser editor: 2.30.0. Direct dependencies are pinned in package.json.

## Try it

Open, edit and export the public sample. Your application owns access, storage and version history.

The included public DOCX is the original homepage sample. It is not your uploaded document or the current edited demo state. Export a separate DOCX, then reopen it in Word or SuperDoc. Built-in and custom review examples use Suggesting mode. The application form fills text fields directly.

## Files

- package.json
- examples/editor/main.ts
- examples/editor/index.html
- examples/shared/browser.ts
- examples/shared/style.css
- vite.config.ts
- tsconfig.json
- public/SuperDoc.docx

## Continue

[Current documentation](https://docs.superdoc.dev/editor/quickstart/)
[Try the homepage demo](https://www.superdoc.dev/?doc=ai#editor)
[SuperDoc licensing](https://docs.superdoc.dev/editor/license/)

The shared browser.ts file contains the export button, status messages and CSS imports. Document setup and task logic are in main.ts.

## Complete source

### package.json

```json
{
  "name": "superdoc-editor",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "engines": {
    "node": ">=22"
  },
  "scripts": {
    "dev": "vite --open /examples/editor/",
    "build": "vite build",
    "check": "tsc --noEmit"
  },
  "dependencies": {
    "superdoc": "2.30.0"
  },
  "devDependencies": {
    "vite": "6.4.1",
    "typescript": "5.8.3"
  }
}
```

### examples/editor/main.ts

```javascript
import { SuperDoc } from 'superdoc';
import { enableExport, showError } from '../shared/browser';

new SuperDoc({
  selector: '#editor',
  document: '/SuperDoc.docx',
  documentMode: 'editing',
  ui: { toolbar: { container: '#toolbar', responsiveTo: 'container' } },
  onReady: ({ superdoc }) => enableExport(superdoc),
  onContentError: ({ error }) => showError(error),
  onException: ({ error }) => showError(error),
});
```

### examples/editor/index.html

```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Embed a DOCX editor | SuperDoc example</title>
<meta name="description" content="Embed a DOCX editor using SuperDoc and the homepage sample.">
<link rel="canonical" href="https://www.superdoc.dev/examples/editor/index.html">
<link rel="alternate" type="text/markdown" href="https://www.superdoc.dev/examples/editor.md">
</head>
<body>
<header>
<h1>Embed a DOCX editor</h1>
<p>Start with the public sample, then replace the document URL with a file your application is authorized to load. Uploaded files and shared room contents are never included in this project.</p>
<div class="actions">
<button id="export" type="button" disabled>Export DOCX</button>
<output id="status" role="status">Opening document…</output>
</div>
<p>
<a href="https://docs.superdoc.dev/editor/quickstart/">Current documentation</a> · <a href="https://www.superdoc.dev/examples/editor.zip">Download this project</a> · <a href="https://www.superdoc.dev/examples/editor.md">Read the complete source</a>
</p>
</header>
<div id="toolbar">
</div>
<main class="solo">
<div id="editor">
</div>
</main>
<script type="module" src="./main.ts">
</script>
</body>
</html>
```

### examples/shared/browser.ts

```javascript
import type { SuperDoc } from 'superdoc';
import 'superdoc/style.css';
import './style.css';

export function element<T extends HTMLElement>(id: string): T {
  const node = document.getElementById(id);
  if (!node) throw new Error(`Missing element: ${id}`);
  return node as T;
}

const status = element<HTMLOutputElement>('status');
const exportButton = element<HTMLButtonElement>('export');
export function report(message: string) { status.value = message; }
export function showError(error: unknown) {
  report(error instanceof Error ? error.message : String(error));
}

export function enableExport(superdoc: SuperDoc) {
  report('Ready. Edit the document, then export a copy.');
  exportButton.disabled = false;
  exportButton.addEventListener('click', async () => {
    exportButton.disabled = true;
    try {
      await superdoc.export({ exportType: ['docx'], exportedName: 'edited-example', triggerDownload: true });
      report('DOCX exported. Open the saved file to check your changes.');
    } catch (error) { showError(error); }
    finally { exportButton.disabled = false; }
  });
}
```

### examples/shared/style.css

```css
:root { font-family: system-ui, sans-serif; color: #242424; background: #f5f5f5; }
#editor { --sd-caret-color: #242424; }
input, textarea, [contenteditable="true"] { caret-color: #242424; }
* { box-sizing: border-box; }
body { margin: 0; }
header { padding: 1rem; border-bottom: 1px solid #ddd; background: white; }
h1 { font-size: 1.2rem; margin: 0 0 .5rem; }
p { line-height: 1.5; }
button, input { font: inherit; padding: .5rem .7rem; min-height: 44px; }
button { cursor: pointer; }
button:disabled { cursor: wait; }
label { display: grid; gap: .3rem; margin-bottom: .7rem; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: .7rem; }
main { display: grid; grid-template-columns: minmax(0, 1fr) 300px; }
main.solo { display: block; }
#editor { height: 76vh; overflow: auto; min-width: 0; }
aside { padding: 1rem; background: white; overflow: auto; max-height: 76vh; }
ul { list-style: none; padding: 0; }
li { border-bottom: 1px solid #ddd; padding: .7rem 0; }
li button { margin: .2rem; }
input { width: 100%; }
@media (max-width: 760px) { main { grid-template-columns: minmax(0, 1fr); } aside { max-height: none; } }
```

### vite.config.ts

```javascript
import { defineConfig } from 'vite';
import { resolve } from 'node:path';
export default defineConfig({
  optimizeDeps: { exclude: ['@superdoc/docx-engine'], include: ['vue'] },
  resolve: { dedupe: ['vue'] },
  build: { rollupOptions: { input: resolve('examples/editor/index.html') } },
});
```

### tsconfig.json

```json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "lib": [
      "ES2022",
      "DOM",
      "DOM.Iterable"
    ],
    "strict": true,
    "skipLibCheck": true,
    "noEmit": true,
    "types": []
  },
  "include": [
    "examples/**/*.ts"
  ]
}
```

[Download the project](https://www.superdoc.dev/examples/editor.zip)
[Download the public sample](https://www.superdoc.dev/SuperDoc.docx)
