Contribute to this guideReport an issue

CKEditor 4 React Integration Documentation

The React integration allows you to implement CKEditor 4 as a React component, using the <CKEditor /> JSX tag.

The following examples showcase the most important features of the CKEditor 4 WYSIWYG editor React integration.

Click the tab below to change an example.

Get Sample Source Code

  • Classic editor
                    import ReactDOM from 'react-dom';
    import CKEditor from 'ckeditor4-react';
    
    ReactDOM.render(
    	<CKEditor data="<p>This is a CKEditor 4 instance created by ️⚛️ React.</p>" />,
    	document.getElementById( 'app' )
    );
  • Inline editor
                    import ReactDOM from 'react-dom';
    import CKEditor from 'ckeditor4-react';
    
    ReactDOM.render(
    	<CKEditor type="inline" data="<p>This is a CKEditor 4 instance created by ️⚛️ React.</p>" />,
    	document.getElementById( 'app' )
    );
  • Editor with custom event handlers and configuration
                    import ReactDOM from 'react-dom';
    import CKEditor from 'ckeditor4-react';
    
    ReactDOM.render(
    	<CKEditor
    		data="I'm a CKEditor 4 instance."
    		config={{
    			toolbar: [
    				[ 'Bold', 'Italic' ],
    				[ 'Cut', 'Copy' ],
    				[ 'About' ]
    			]
    		}}
    		onFocus={customHandler}
    		onBlur={customHandler}
    		onChange={customHandler}
    		onSelectionChange={customHandler}
    	/>,
    	document.getElementById( 'app' )
    );
    
    function customHandler( evt ) {
    	console.log( evt );
    }
  • Two-way data binding
                    import React, { Component } from 'react';
    import ReactDOM from 'react-dom';
    import CKEditor from 'ckeditor4-react';
    
    class TwoWayBinding extends Component {
    	constructor( props ) {
    		super( props );
    
    		this.state = {
    			data: '<p>This is a CKEditor 4 instance created by ️⚛️ React.</p>'
    		};
    
    		this.handleChange = this.handleChange.bind( this );
    		this.onEditorChange = this.onEditorChange.bind( this );
    	}
    
    	onEditorChange( evt ) {
    		this.setState( {
    			data: evt.editor.getData()
    		} );
    	}
    
    	handleChange( changeEvent ) {
    		this.setState( {
    			data: changeEvent.target.value
    		} );
    	}
    
    	render() {
    		return (
    			<div>
    				<SourceEditor data={this.state.data} handler={this.handleChange} />
    
    				<div style={{overflow: 'auto'}}>
    					<CKEditor
    						data={this.state.data}
    						onChange={this.onEditorChange}
    						style={{
    							float: 'left',
    							width: '50%'
    						}}
    					/>
    					<EditorPreview data={this.state.data} />
    				</div>
    			</div>
    		);
    	}
    }
    
    class EditorPreview extends Component {
    	render() {
    		return (
    			<div className="editor-preview">
    				<h2>Rendered content</h2>
    				<div dangerouslySetInnerHTML={{ __html: this.props.data }}></div>
    			</div>
    		);
    	}
    }
    
    class SourceEditor extends Component {
    	constructor( props ) {
    		super( props );
    
    		this.state = {
    			focused: false
    		};
    	}
    
    	render() {
    		var textareaValue = {};
    
    		if ( !this.state.focused ) {
    			textareaValue = {
    				value: this.props.data
    			};
    		}
    
    		return (
    			<>
    				<p>
    					<label htmlFor="editor-editor">The editor content:</label>
    				</p>
    				<p>
    					<textarea
    						id="editor-editor"
    						className="binding-editor"
    						{...textareaValue}
    						onChange={this.props.handler}
    						onFocus={ () => { this.setState( {
    								focused: true
    							} );
    						}}
    						onBlur={ () => { this.setState( {
    								focused: false
    							} );
    						}}
    					/>
    				</p>
    			</>
    		);
    	}
    }
    
    ReactDOM.render( <TwoWayBinding />, document.getElementById( 'app' ) );