Three components cover the full rich text lifecycle: RichText for read-only display, RichTextEditor for standalone editing, and CoreFormRichTextEditor for use inside a CoreForm.
Displaying content
Use RichText to render stored HTML with Tailwind typography styles applied.
import RichText from '@core/components/rich-text';
<RichText html={question.content} />
Pass className to extend the default styles (e.g. add a border, background, or constrain width):
<RichText html={content} className="rounded-lg border bg-muted/30 p-4" />
The component applies prose prose-sm dark:prose-invert max-w-none by default, so headings, lists, links, and other HTML elements are rendered correctly.
Editing content in a form
Inside a CoreForm, use CoreFormRichTextEditor. It wires directly into the Inertia form context—no extra state needed.
import { CoreForm, CoreFormRichTextEditor, CoreFormSubmitButton } from '@core/components/core-form';
import { useForm } from '@inertiajs/react';
const form = useForm({ content: '' });
<CoreForm form={form} onSubmit={() => form.patch(route('questions.update', question))}>
<CoreFormRichTextEditor name="content" label={__('Content')} />
<CoreFormSubmitButton />
</CoreForm>
Standalone editor
When you need the editor outside a CoreForm, use RichTextEditor directly and manage the value yourself.
import RichTextEditor from '@core/components/rich-text-editor';
const [content, setContent] = useState('');
<RichTextEditor value={content} onChange={setContent} />
All toolbar buttons are enabled by default. Pass a features prop to restrict them.
| Option | Type | Default | Description |
|---|
bold | boolean | true | Bold text |
italic | boolean | true | Italic text |
strike | boolean | true | Strikethrough |
link | boolean | true | Insert / remove hyperlinks |
bulletList | boolean | true | Unordered list |
orderedList | boolean | true | Ordered list |
hardBreak | boolean | true | Hard line break |
removeFormatting | boolean | true | Strip all marks |
undo | boolean | true | Undo |
redo | boolean | true | Redo |
headings | number[] | [] | Heading levels to show, e.g. [2, 3] |
Enable only the features you need:
<CoreFormRichTextEditor
name="content"
label={__('Content')}
features={{
bold: true,
italic: true,
bulletList: true,
headings: [2, 3],
strike: false,
link: false,
removeFormatting: false,
hardBreak: false,
undo: false,
redo: false,
orderedList: false,
}}
/>
Activity log
When a rich text field is logged in the activity log, return ActivityValueFormatter::richText() from formatActivityLogAttributeValue(). This prevents raw HTML from appearing in the diff and instead shows a “Show difference” button that opens a modal with the before and after content rendered side by side.
use Inly\Core\Support\ActivityLog\ActivityValueFormatter;
public function formatActivityLogAttributeValue(string $key, mixed $value): mixed
{
return match ($key) {
'content' => ActivityValueFormatter::richText($value),
default => null,
};
}
See the Activity Log docs (coming soon) for the full formatting pipeline.