⚛️ React Integration Guide

Use Kria Lite WYSIWYG Editor in React

Learn how to integrate the lightweight Kria Lite WYSIWYG editor into your React application. This guide covers installation, React hooks, TypeScript support, and best practices.

⏱️ Time: 5 minutes
📦 Size: ~6KB added
📚 Level: Beginner

📋 Prerequisites

  • React 16.8+ (for hooks support)
  • Node.js and npm/yarn installed
  • Basic understanding of React components
1

Installation

Install Kria Lite WYSIWYG editor using npm or yarn:

# Using npm npm install kria-lite # Using yarn yarn add kria-lite # Using pnpm pnpm add kria-lite

The package includes both the JavaScript library and CSS styles. No additional dependencies required!

2

Basic Usage

Here's the simplest way to use Kria Lite in a React component:

import React, { useEffect, useRef } from 'react'; import { WYSIWYG } from 'kria-lite'; import 'kria-lite/dist/kria.editor.css'; function Editor() { const editorRef = useRef(null); const instanceRef = useRef(null); useEffect(() => { // Initialize the editor if (editorRef.current && !instanceRef.current) { instanceRef.current = WYSIWYG.init(editorRef.current, { height: '300px', placeholder: 'Start writing...' }); } // Cleanup on unmount return () => { if (instanceRef.current) { instanceRef.current.destroy(); instanceRef.current = null; } }; }, []); return ( <div> <textarea ref={editorRef} /> </div> ); } export default Editor;
3

Custom React Hook

Create a reusable hook for better code organization:

// hooks/useKriaEditor.js import { useEffect, useRef, useCallback } from 'react'; import { WYSIWYG } from 'kria-lite'; export function useKriaEditor(options = {}) { const editorRef = useRef(null); const instanceRef = useRef(null); useEffect(() => { if (editorRef.current && !instanceRef.current) { instanceRef.current = WYSIWYG.init(editorRef.current, { height: '300px', ...options }); } return () => { if (instanceRef.current) { instanceRef.current.destroy(); instanceRef.current = null; } }; }, []); const getContent = useCallback(() => { return instanceRef.current?.getContent() || ''; }, []); const setContent = useCallback((html) => { instanceRef.current?.setContent(html); }, []); const focus = useCallback(() => { instanceRef.current?.focus(); }, []); return { editorRef, getContent, setContent, focus, instance: instanceRef }; }

Use the hook in your components:

import { useKriaEditor } from './hooks/useKriaEditor'; function BlogEditor() { const { editorRef, getContent, setContent } = useKriaEditor({ placeholder: 'Write your blog post...', imageUploadUrl: '/api/upload' }); const handleSave = () => { const content = getContent(); console.log('Saving:', content); // Save to your backend }; return ( <div> <textarea ref={editorRef} /> <button onClick={handleSave}>Save</button> </div> ); }
4

TypeScript Support

Kria Lite includes TypeScript definitions. Here's a typed version of the hook:

// hooks/useKriaEditor.ts import { useEffect, useRef, useCallback } from 'react'; import { WYSIWYG, EditorOptions, EditorInstance } from 'kria-lite'; interface UseKriaEditorResult { editorRef: React.RefObject<HTMLTextAreaElement>; getContent: () => string; setContent: (html: string) => void; focus: () => void; instance: React.RefObject<EditorInstance | null>; } export function useKriaEditor( options: Partial<EditorOptions> = {} ): UseKriaEditorResult { const editorRef = useRef<HTMLTextAreaElement>(null); const instanceRef = useRef<EditorInstance | null>(null); useEffect(() => { if (editorRef.current && !instanceRef.current) { instanceRef.current = WYSIWYG.init(editorRef.current, { height: '300px', ...options }); } return () => { instanceRef.current?.destroy(); instanceRef.current = null; }; }, []); const getContent = useCallback((): string => { return instanceRef.current?.getContent() ?? ''; }, []); const setContent = useCallback((html: string): void => { instanceRef.current?.setContent(html); }, []); const focus = useCallback((): void => { instanceRef.current?.focus(); }, []); return { editorRef, getContent, setContent, focus, instance: instanceRef }; }
5

Controlled Component

Create a fully controlled WYSIWYG component with onChange support:

import React, { useEffect, useRef } from 'react'; import { WYSIWYG } from 'kria-lite'; interface RichEditorProps { value: string; onChange: (html: string) => void; placeholder?: string; height?: string; } export function RichEditor({ value, onChange, placeholder = 'Start writing...', height = '300px' }: RichEditorProps) { const editorRef = useRef<HTMLTextAreaElement>(null); const instanceRef = useRef<any>(null); const isInternalChange = useRef(false); useEffect(() => { if (editorRef.current && !instanceRef.current) { instanceRef.current = WYSIWYG.init(editorRef.current, { height, placeholder, onChange: (content: string) => { isInternalChange.current = true; onChange(content); isInternalChange.current = false; } }); // Set initial value if (value) { instanceRef.current.setContent(value); } } return () => { instanceRef.current?.destroy(); instanceRef.current = null; }; }, []); // Sync external value changes useEffect(() => { if (instanceRef.current && !isInternalChange.current) { const currentContent = instanceRef.current.getContent(); if (currentContent !== value) { instanceRef.current.setContent(value); } } }, [value]); return <textarea ref={editorRef} />; }

Usage with React state:

function App() { const [content, setContent] = useState('<p>Initial content</p>'); return ( <RichEditor value={content} onChange={setContent} placeholder="Write something amazing..." /> ); }
6

Image Upload Configuration

Configure image uploads with your backend API:

const editor = WYSIWYG.init(editorRef.current, { imageUploadUrl: '/api/upload', imageUploadHeaders: { 'Authorization': `Bearer ${token}` }, imageUploadParams: { 'folder': 'blog-images' }, onImageUpload: (response) => { // Return the image URL from your API response return response.url; }, onImageUploadError: (error) => { console.error('Upload failed:', error); alert('Failed to upload image'); } });
7

Form Integration

Integrate with popular form libraries like React Hook Form:

import { Controller } from 'react-hook-form'; import { RichEditor } from './RichEditor'; function BlogForm({ control }) { return ( <form> <Controller name="content" control={control} defaultValue="" render={({ field }) => ( <RichEditor value={field.value} onChange={field.onChange} placeholder="Write your post content..." /> )} /> </form> ); }
8

Best Practices

✅ Do: Clean up on unmount

Always call destroy() when the component unmounts to prevent memory leaks.

✅ Do: Lazy load for performance

Use React.lazy() to load the editor only when needed, reducing initial bundle size.

❌ Don't: Re-initialize on every render

Store the editor instance in a ref and only initialize once. Multiple initializations will cause performance issues.

❌ Don't: Trust user HTML blindly

Even though Kria Lite has XSS protection, always sanitize HTML on the server before storing or displaying user-generated content.

Next Steps

You now have Kria Lite WYSIWYG editor running in your React application! Here are some resources to continue learning: