Skip to main content

@clepit/react

The @clepit/react package provides React components for the Clepit editor: ClepitContent, which emits finished HTML on the server, and ClepitEditor, a client-only component that owns the Editor.create lifecycle.

npm: @clepit/react · npm: @clepit/core

Install

Shell
bun add @clepit/core @clepit/react

ClepitContent

ClepitContent draws a document to finished HTML through renderBlocks, so it works in Server Components, during SSR, and in the browser. The markup is in the initial response: crawlers read it, and nothing repaints on mount. The core stylesheet rides along as a tag deduplicated by React.

TypeScript
import { ClepitContent } from '@clepit/react';

export const Article = ({ document }) => <ClepitContent data={document} />;

Interactive blocks come alive after mount through activateBlocks from @clepit/core: code variant tabs, language sync and the copy button, openapi response tabs, and the table CSV download all work on the server-drawn markup; only the interactive blocks data crosses to the browser.

Optional props:

FieldTypeRequiredDescription
theme'auto' | 'light' | 'dark'No'auto'
themeOverrides{ light?, dark? }NoThemeTokens
context{ docHref?, mapsEmbedKey?, activeVariant? }No
transformHtml(html: string) => stringNo
classNamestringNo
testIdstringNo

ClepitEditor

ClepitEditor is client-only and lives on its own subpath, so importing the display component never pulls editing code into a server bundle. The component owns the Editor.create lifecycle: effect timing and StrictMode-safe teardown.

TypeScript
'use client';

import { ClepitEditor } from '@clepit/react/editor';

export const Compose = ({ initialData, onSave }) => (
  <ClepitEditor
    initialData={initialData}
    onChange={data => onSave(data)}
    placeholder='Start writing'
  />
);

Props are EditorConfig from @clepit/core minus containerId (the component renders its own holder), plus id, className, testId, and onApi, which receives the EditorAPI returned by Editor.create. The editor is uncontrolled: value fields are read once at mount, callbacks always see the latest render props, and unmounting destroys the instance.