# Open and edit your first DOCX

> Install the browser Editor, open a sample DOCX, and export your first edit.



Choose Vanilla or React below. Your choice stays active for every code example on this page.

## 1. Create a project [#1-create-a-project]

Create a Vite project, enter it, and install SuperDoc:

**Vanilla — `Terminal`**

```sh
pnpm create vite@latest superdoc-quickstart --template vanilla-ts
cd superdoc-quickstart
pnpm add superdoc

```

**React — `Terminal`**

```sh
pnpm create vite@latest superdoc-quickstart --template react-ts
cd superdoc-quickstart
pnpm add @superdoc/react

```


## 2. Add the sample document [#2-add-the-sample-document]

Download the sample and save it as `public/sample.docx`:

[Download the sample document](/fixtures/getting-started.docx): One-page statement of work · DOCX


Vite serves `public/sample.docx` at `/sample.docx`.

## 3. Add the page [#3-add-the-page]

Add the application surface. Vanilla mounts SuperDoc into `#editor`; the React wrapper creates that container for you.

**Vanilla — `index.html`**

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>SuperDoc vanilla quickstart</title>
  </head>
  <body>
    <button id="export-docx" type="button" disabled>Export DOCX</button>
    <div id="editor"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

```

**React — `src/main.tsx`**

```tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
import './index.css';

const root = document.querySelector('#root');
if (!root) throw new Error('The React root is missing.');

createRoot(root).render(
  <StrictMode>
    <App />
  </StrictMode>,
);

```


## 4. Open the document [#4-open-the-document]

Add the Editor and enable export after the document opens:

**Vanilla — `src/main.ts`**

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

const exportButton = document.querySelector<HTMLButtonElement>('#export-docx');

if (!exportButton) throw new Error('The export button is missing.');

const superdoc = new SuperDoc({
  selector: '#editor',
  document: '/sample.docx',
  onReady: () => {
    exportButton.disabled = false;
  },
  onContentError: ({ error }) => {
    console.error('SuperDoc could not open the document.', error);
  },
  onException: ({ error }) => {
    console.error('SuperDoc could not open the document.', error);
  },
});

exportButton.addEventListener('click', async () => {
  exportButton.disabled = true;
  try {
    await superdoc.export({ exportType: ['docx'], exportedName: 'sample-edited' });
  } catch (error) {
    console.error('SuperDoc could not export the document.', error);
  } finally {
    exportButton.disabled = false;
  }
});

```

**React — `src/App.tsx`**

```tsx
import { useRef, useState } from 'react';
import { SuperDocEditor, type SuperDocRef } from '@superdoc/react';
import '@superdoc/react/style.css';

export default function App() {
  const editorRef = useRef<SuperDocRef>(null);
  const exportingRef = useRef(false);
  const [ready, setReady] = useState(false);
  const [exporting, setExporting] = useState(false);

  async function exportDocument() {
    if (exportingRef.current) return;
    exportingRef.current = true;
    setExporting(true);
    try {
      await editorRef.current?.getInstance()?.export({ exportType: ['docx'], exportedName: 'sample-edited' });
    } catch (error) {
      console.error('SuperDoc could not export the document.', error);
    } finally {
      exportingRef.current = false;
      setExporting(false);
    }
  }

  return (
    <main>
      <button disabled={!ready || exporting} onClick={() => void exportDocument()} type='button'>
        Export DOCX
      </button>
      <SuperDocEditor
        document='/sample.docx'
        onContentError={({ error }) => console.error('SuperDoc could not open the document.', error)}
        onException={({ error }) => console.error('SuperDoc could not open the document.', error)}
        onReady={() => setReady(true)}
        ref={editorRef}
      />
    </main>
  );
}

```


Run the project:

```bash
pnpm dev
```

Open the printed URL. When the statement of work appears, **Export DOCX** becomes enabled. `onReady` keeps the button
disabled until the document is open.

## 5. Make an edit and export [#5-make-an-edit-and-export]

Change the effective date from `September 1, 2026` to `October 1, 2026`. Then select **Export DOCX**. The browser
downloads `sample-edited.docx`.

> **Check the exported document (success)**
>
> Open `sample-edited.docx` in Word or SuperDoc. Confirm that the effective date is `October 1, 2026` and that the
> title, service list, milestone table, and signatures keep their formatting.


## What just happened [#what-just-happened]

* `selector` mounted the Vanilla Editor; the React wrapper owned its container.
* `document` gave the browser a DOCX URL to open.
* `onReady` marked the first safe moment to enable document actions.
* `export()` created the edited DOCX and triggered the download.

If the document does not appear, check the `onContentError` or `onException` message in the browser console. They
report import and startup failures instead of leaving an unexplained empty mount point.

The complete projects are available for [Vanilla](https://go.superdoc.dev/examples/vanilla) and
[React](https://go.superdoc.dev/examples/react).

## Continue to configuration [#continue-to-configuration]

[Configure the Editor](/editor/configuration) to add user information, choose a document mode, and handle startup
errors while keeping the same `/sample.docx` project.
