Remix example

This Remix and Vite example loads the React editor after the route mounts.

Run the example

From the repository root, build the workspace packages before you start Remix:

bun install
bun run build:packages
bun run dev:remix

Open http://localhost:3001.

Set the client boundary

app/routes/_index.tsx uses a mount check and a lazy import:

import { lazy, Suspense, useEffect, useState } from 'react';

const Editor = lazy(() => import('../components/Editor').then((m) => ({ default: m.Editor })));

export default function Index() {
  const [mounted, setMounted] = useState(false);
  useEffect(() => setMounted(true), []);

  if (!mounted) return <div>Loading editor...</div>;
  return (
    <Suspense fallback={<div>Loading editor...</div>}>
      <Editor />
    </Suspense>
  );
}

The mount check keeps the server markup and first client markup identical. The lazy import keeps the editor out of the server build.

Add the editor to Remix

npm install @docx-editor.dev/react @docx-editor.dev/core

Import @docx-editor.dev/core/styles/editor.css once. Render the editor only after the component mounts.

For more information, see the Remix integration guide.

Next steps

This page renders the example’s README from eigenpal/docx-editor at release v2.21.0. Read it in the repository for the version you have checked out.

.docx in. .docx out.

Open a real document in the editor, then wire it into your app. It all runs client-side.