---
title: Integrate a Third-Party Rich Content Editor
product: Survey Creator
description: Learn how to transform text entry fields within the Property Grid into powerful rich text editors for easy and precise text formatting. View this free demo to explore the capabilities of a WYSIWYG visual editor and access a code example for JavaScript to discover how to seamlessly integrate Quill into your SurveyJS form-building tool.
framework: React
source: https://surveyjs.io/survey-creator/examples/form-builder-with-integrated-rich-text-editor/reactjs
index: https://surveyjs.io/survey-creator/examples/overview.md
---

# Integrate a Third-Party Rich Content Editor (React)

In addition to multiple configuration options available by default, SurveyJS Creator supports various customizations. For instance, you can replace text entry fields within the Property Grid (the input fields you use to enter a title or form description) with dedicated rich text editors. A rich text editor is a WYSIWYG visual editor that provides an input area for editing your form's content and a toolbar equipped with all the necessary formatting tools. Survey creators can apply bold, italic, or underline font style to text, add bullet points or numbered lists, insert hyperlinks, adjust text alignment, and more. This demo illustrates how to integrate a third-party <a href="https://quilljs.com/" target="_blank">Quill</a> text editor into Survey Creator.

For a step-by step Quill integration tutorial, refer to the following documentation articles. Although they describe integration of a color picker, the same instructions apply to any other third-party component, including Quill. 

- [Integrate Third-Party React Components](https://surveyjs.io/form-library/documentation/customize-question-types/third-party-component-integration-react)
- [Integrate Third-Party Angular Components](https://surveyjs.io/form-library/documentation/customize-question-types/third-party-component-integration-angular)
- [Integrate Third-Party Vue 3 Components](/form-library/documentation/customize-question-types/third-party-component-integration-vue)

## Files

### `public/index.html`

```html
<!-- Uncomment the following lines to enable Ace Editor in the JSON Editor tab -->
<!-- 
<script src="https://unpkg.com/ace-builds/src-min-noconflict/ace.js"></script>
<script src="https://unpkg.com/ace-builds/src-min-noconflict/ext-searchbox.js"></script>
<script src="https://unpkg.com/ace-builds/src-min-noconflict/theme-clouds_midnight.js"></script>
-->

<div id="surveyCreatorContainer" style="position: absolute; height: 100%; width: 100%"></div>
```

### `src/QuillComponent.jsx`

```js
import React from "react";
import { ElementFactory, Question, Serializer } from "survey-core";
import ReactQuill from "react-quill-new";
import "react-quill-new/dist/quill.snow.css";
import {
    SurveyQuestionElementBase,
    ReactQuestionFactory
} from "survey-react-ui";
import { PropertyGridEditorCollection } from "survey-creator-core";

// Must use lowercase
const CUSTOM_TYPE = "quill";

// Create a question model
export class QuestionQuillModel extends Question {
    getType() {
        return CUSTOM_TYPE;
    }
    get height() {
        return this.getPropertyValue("height");
    }
    set height(val) {
        this.setPropertyValue("height", val);
    }
}

// Register the model in `ElementFactory`
ElementFactory.Instance.registerElement(CUSTOM_TYPE, (name) => {
    return new QuestionQuillModel(name);
});

// Add question type metadata for further serialization into JSON
Serializer.addClass(
    CUSTOM_TYPE,
    [{ name: "height", default: "200px", category: "layout" }],
    function () {
        return new QuestionQuillModel("");
    },
    "question"
);

// Create a class that renders Quill
export class SurveyQuestionQuill extends SurveyQuestionElementBase {
    constructor(props) {
        super(props);
    }
    get question() {
        return this.questionBase;
    }
    get value() {
        return this.question.value;
    }
    handleValueChange = (val) => {
        this.question.value = val;
    };
    get style() {
        return { height: this.question.height };
    }

    renderQuill() {
        // Support the read-only and design modes
        const isReadOnly = this.question.isReadOnly || this.question.isDesignMode;
        return (
            <ReactQuill
                readOnly={isReadOnly}
                value={this.value}
                onChange={this.handleValueChange}
            />
        );
    }

    renderElement() {
        return <div style={this.style}>{this.renderQuill()}</div>;
    }
}

// Register `SurveyQuestionQuill` as a class that renders `quill` questions
ReactQuestionFactory.Instance.registerQuestion(CUSTOM_TYPE, (props) => {
    return React.createElement(SurveyQuestionQuill, props);
});

// Register `quill` as an editor for properties of the `text` and `html` types in the Survey Creator's Property Grid
PropertyGridEditorCollection.register({
    fit: function (prop) {
        return prop.type == "text" || prop.type == "html";
    },
    getJSON: function () {
        return { type: "quill" };
    }
});
```

### `src/SurveyCreatorComponent.jsx`

```js
import React from "react";
import { SurveyCreator, SurveyCreatorComponent } from "survey-creator-react";
import "survey-core/survey.i18n";
import "survey-creator-core/survey-creator-core.i18n";
import { SurveyQuestionQuill } from "./QuillComponent";
import { getLocaleStrings } from "survey-creator-core";
import "survey-core/survey-core.css";
import "survey-creator-core/survey-creator-core.css";
import "./index.css";

import SurveyTheme from "survey-core/themes";
import { registerCreatorTheme } from "survey-creator-core";

registerCreatorTheme(SurveyTheme); // Add predefined Survey Creator UI themes

function applyHtml(_, options) {
    let str = options.text;
    if (str.indexOf("<p>") === 0) {
        // Remove root paragraphs <p></p>
        str = str.substring(3);
        str = str.substring(0, str.length - 4);
    }
    // Set HTML markup to render
    options.html = str;
}

// Specify a title for the toolbox category that will contain the Quill question type  
const translations = getLocaleStrings("en");
translations.toolboxCategories["custom"] = "Custom Questions";
function SurveyCreatorRenderComponent() {
    const creator = new SurveyCreator();
    // Move the Quill question type to the first position in the Toolbox
    const toolboxItems = creator.toolbox.items;
    const quillIndex = toolboxItems.findIndex((item) => item.name === "quill");
    const quillItem = toolboxItems.splice(quillIndex, 1)[0];
    quillItem.title = "Rich Text Editor";
    quillItem.iconName = "icon-comment";
    toolboxItems.unshift(quillItem);
    creator.toolbox.changeCategory("quill", "custom");
    
    // Apply HTML markup to survey contents
    creator.survey.onTextMarkdown.add(applyHtml);
    creator.onSurveyInstanceSetupHandlers.add((_, options) => {    
        options.survey.onTextMarkdown.add(applyHtml);    
    });
    
    creator.JSON = {
        "title": "Quill Integration with SurveyJS",
        "description": "<ul><li><strong>Bold</strong></li><li><em>Italics</em></li><li><s>Strikethrough</s></li></ul>",
        "pages": [{
            "name": "page1",
            "elements": [{
                "type": "quill",
                "name": "rich-text-editor",
                "title": "Rich Text Editor",
                "defaultValue": "Hello world!"
            }]
        }]
    }
    
    return (<SurveyCreatorComponent creator={creator} />);
}

export default SurveyCreatorRenderComponent;
```

### `src/index.css`

```css
.ql-toolbar.ql-snow {
    white-space: normal;
}
.sv-string-editor--html {
    white-space: normal !important;
}
.quill .ql-container {
    max-height: calc(100% - 42px);
}
```

### `src/index.js`

```js
import React from "react";
import { createRoot } from "react-dom/client";
import SurveyCreatorRenderComponent from "./SurveyCreatorComponent";

const root = createRoot(document.getElementById("surveyCreatorContainer"));
root.render(<SurveyCreatorRenderComponent />);
```

### `package.json`

```json
{
  "dependencies": {
    "react": "latest",
    "react-dom": "latest",
    "react-quill-new": "latest",
    "survey-core": "latest",
    "survey-react-ui": "latest",
    "survey-creator-core": "latest",
    "survey-creator-react": "latest"
  },
  "devDependencies": {
    "react-scripts": "latest"
  }
}
```

## Other Frameworks

- [Angular](https://surveyjs.io/survey-creator/examples/form-builder-with-integrated-rich-text-editor/angular.md)
- [Vue 3](https://surveyjs.io/survey-creator/examples/form-builder-with-integrated-rich-text-editor/vue3js.md)
- [jQuery](https://surveyjs.io/survey-creator/examples/form-builder-with-integrated-rich-text-editor/jquery.md)
