RichTextEditor
The main React component for embedding Inkstream.
Import
import { RichTextEditor } from '@inkstream/react-editor'Props
| Prop | Type | Default | Description |
|---|---|---|---|
initialContent | string | '' | Initial HTML content |
plugins | Plugin[] | all built-in plugins | Plugin instances to register |
pluginOptions | Record<string, unknown> | {} | Per-plugin options forwarded to getToolbarItems |
toolbarLayout | (string | '|')[] | [] (all items) | Ordered toolbar item IDs; `' |
licenseKey | string | — | License key string |
licenseValidationEndpoint | string | — | URL of your server-side POST validation endpoint |
onLicenseError | (plugin, tier) => void | — | Called when a plugin’s tier requirement is not met |
onChange | (html: string) => void | — | Called on every content change with serialized HTML |
onEditorReady | (view: EditorView) => void | — | Called once with the EditorView instance after mount |
theme | ThemeMode | 'auto' | Colour scheme: 'auto' (OS), 'light', or 'dark' |
showThemeToggle | boolean | false | Adds an Auto/Light/Dark switcher button at the right end of the toolbar |
onThemeChange | (theme: ThemeMode) => void | — | Called when the theme changes (toggle click or prop change) |
Example
import { RichTextEditor } from '@inkstream/react-editor'
import { availablePlugins } from "@inkstream/starter-kit"
<RichTextEditor
plugins={[availablePlugins.paragraph, availablePlugins.bold, availablePlugins.italic, availablePlugins.history]}
initialContent="<p>Hello</p>"
toolbarLayout={['bold', 'italic', '|', 'undo', 'redo']}
onChange={(html) => setValue(html)}
licenseValidationEndpoint="/api/validate-license"
licenseKey={licenseKey}
showThemeToggle
/>ThemeMode type
import type { ThemeMode } from '@inkstream/react-editor'
// 'auto' | 'light' | 'dark'See the Theming & Dark Mode guide for full usage examples.
useLicenseValidation
import { useLicenseValidation } from '@inkstream/react-editor'
const {
tier, // 'free' | 'pro' | 'premium' — server-validated
isValidating, // boolean
error, // string | null
} = useLicenseValidation({
licenseKey: 'INKSTREAM-PRO-ABC123',
validationEndpoint: '/api/validate-license',
})Without validationEndpoint, tier is always 'free'. The system is secure by default — never derives tier from the key string alone.
useLazyPlugins
import { useLazyPlugins } from '@inkstream/react-editor'
const {
loadedPlugins, // Plugin[] — empty until loaded
isLoading, // boolean
error, // string | null
} = useLazyPlugins({
validatedTier, // from useLicenseValidation
lazyPlugins: [
{
loader: (tier) =>
import('@inkstream/pro-plugins').then(m => ({ table: m.createProPlugins(tier).table })),
requiredTier: 'pro',
pluginKey: 'table',
},
],
})The loader function receives the server-validated tier as its first argument. See the Lazy Loading guide for details.
EditorWithTableDialog
EditorWithTableDialog wraps RichTextEditor and adds a table-insertion dialog. It accepts a forwarded ref and all the same props as RichTextEditor.
import { useRef } from 'react'
import { EditorWithTableDialog } from '@inkstream/react-editor'
import type { EditorHandle } from '@inkstream/react-editor'
const editorRef = useRef<EditorHandle>(null)
<EditorWithTableDialog
ref={editorRef}
initialContent="<p>…</p>"
showThemeToggle
onChange={(html) => console.log(html)}
/>
// Imperative API
editorRef.current?.getContent() // → current HTML string
editorRef.current?.focus()