Integration
React Integration
Mount Lextrix in React with refs, MDX/Markdown persistence, and theme-aware styling.
Lextrix is framework-agnostic — the editor owns document state and DOM sync. In React, mount it once with a ref and clean up on unmount.
Basic mount
'use client';
import { useEffect, useRef } from 'react';
import Lextrix from 'lextrix';
import 'lextrix/snow.css';
export function LextrixEditor() {
const containerRef = useRef<HTMLDivElement>(null);
const editorRef = useRef<Lextrix | null>(null);
useEffect(() => {
if (!containerRef.current || editorRef.current) return;
editorRef.current = new Lextrix(containerRef.current, {
theme: 'snow',
placeholder: 'Write something…',
modules: {
toolbar: [
['bold', 'italic'],
[{ header: [1, 2, false] }],
['link'],
],
imageResize: true,
},
});
return () => {
editorRef.current = null;
};
}, []);
return <div ref={containerRef} />;
}Persist as Markdown or MDX
Lextrix 2.x serializers make CMS-style persistence straightforward:
useEffect(() => {
if (!containerRef.current || editorRef.current) return;
const editor = new Lextrix(containerRef.current, { theme: 'snow' });
editorRef.current = editor;
if (initialMarkdown) {
editor.importContent(initialMarkdown, 'markdown');
}
const onChange = () => {
onSave(editor.exportContent('markdown'));
};
editor.on('text-change', onChange);
return () => editor.off('text-change', onChange);
}, []);Swap 'markdown' for 'mdx' or 'html' depending on your backend.
Controlled initial content
Set content after mount — avoid re-creating the editor on every render:
useEffect(() => {
if (!editorRef.current) return;
editorRef.current.setContents([
{ insert: 'Hello from React\n', attributes: { header: 1 } },
{ insert: 'Edit me below.\n' },
]);
}, []);Theme-aware CSS
Import one theme stylesheet globally. For dark mode, swap the CSS import or use the Slate theme:
import 'lextrix/slate.css'; // dark-friendly toolbarPair with your app's next-themes or CSS variables — Lextrix themes are self-contained CSS files.
Avoid common pitfalls
- Do not pass React state as the editor key — remounting destroys undo history.
- Debounce saves when exporting Markdown/MDX on every
text-change. - Use
readOnly: truefor display-only views instead of disabling the DOM manually. - Use
importContent, notLextrix.import()— that is the module loader.
Next steps
- Serialization — import/export API details
- Editor Commands — drive formatting from React buttons
- Why I Started Building Lextrix — design decisions behind the engine