SimpleNext.js
The comprehensive guide to react-quill (for React and Next.js)
Quill is an open source, very modular WYSIWYG rich text editor for web apps, that comes with many useful features. React-quill is a Quill component for use with React and React-based frameworks ( like Next.js), that we already had a first look on here. In this article, we will go more in details to explore all the possibilities offered by react-quill to our React and Next.js apps.
Basic usage of react-quill
You can refer to our previous article to see the basic usage of react-quill for Next.js .
For React apps, we need , like Next.js apps , to install the package :
npm install react-quill --save
then use the ReactQuill component :
import React from "react";
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
function MyComponent() {
return (
<ReactQuill theme="snow" ></ReactQuill>
);
}
the only difference with Next.js is that we import ReactQuill directly instead of dynamically like this :
import React from "react";
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
function MyComponent() {
return (
<ReactQuill theme="snow" />
);
}
So here he we have the core version of the Quill editor without any features. From now on in the article we will use Next.js instead of vanilla React, but all of what will be explained is applicable to Vanilla React also.
Modules
Quill’s behavior and functionality can be customized via Modules. This modules include the ToolBar module, Keyboard, History, ClipBoard and Syntax.
To enable a module, simply include it in Quill’s configuration. In our previous article, we configured the ToolBar module and clipboard module:
const modules = {
toolbar: [
[{ header: '1' }, { header: '2' }, { font: [] }],
[{ size: [] }],
['bold', 'italic', 'underline', 'strike', 'blockquote'],
[
{ list: 'ordered' },
{ list: 'bullet' },
{ indent: '-1' },
{ indent: '+1' },
],
['link', 'image', 'video'],
['clean'],
],
clipboard: {
// toggle to add extra line breaks when pasting HTML:
matchVisual: false,
},
}
then :
export default function Home() {
return <QuillNoSSRWrapper modules={modules} formats={formats} theme="snow" />
}
the result is :
ToolBar, Keyboard and history are required and do not need to be explicitly added , but they are still fully configurable.
ToolBar Module
the toolbar allows the user to edit the text. If we go back to our example, we added these formats to our toolbar :
toolbar: [
[{ header: '1' }, { header: '2' }, { font: [] }],
[{ size: [] }],
['bold', 'italic', 'underline', 'strike', 'blockquote'],
[
{ list: 'ordered' },
{ list: 'bullet' },
{ indent: '-1' },
{ indent: '+1' },
],
['link', 'image', 'video'],
['clean'],
]
each element of the array toolbar is a group of controls, that will be shown separately in the toolbar :
Buttons with custom values can be specified with an Object with the name of the format as its only key.
{ header: '1' }, { header: '2' }
Dropdowns are similarly specified by an Object, but with an array of possible values; if empty the values are default values
{ size: [] }
here is a more detailed look of options for toolbar :
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }], // custom button values
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
[{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent
[{ 'direction': 'rtl' }], // text direction
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'font': [] }],
[{ 'align': [] }],
['clean'] // remove formatting button
Keyboard Module
The Keyboard module enables custom behavior for keyboard events in particular contexts. Quill uses this to bind formatting hotkeys and prevent undesirable browser side effects. Refer here for more in depth information.
History Module
The History module is responsible for handling undo and redo for Quill. It can be configured with the following options:
- delay
Default: 1000 Changes occuring within the delay number of milliseconds is merged into a single change. For example, with delay set to 0, nearly every character is recorded as one change and so undo would undo one character at a time. With delay set to 1000, undo would undo all changes that occured within the last 1000 milliseconds.
- maxStack
Default: 100 Maximum size of the history’s undo/redo stack. Merged changes with the delay option counts as a singular change.
- userOnly
Default: false By default all changes, whether originating from user input or programmatically through the API, are treated the same and change be undone or redone by the history module. If userOnly is set to true, only user changes will be undone or redone.
Formats
Quill supports a number of formats, both in UI controls and API calls. By default all formats are enabled and allowed to exist within a Quill editor and can be configured with the formats option. This is separate from adding a control in the Toolbar. For example, you can configure Quill to allow bolded content to be pasted into an editor that has no bold button in the toolbar.
Inline
- Background Color - background
- Bold - bold
- Color - color
- Font - font
- Inline Code - code
- Italic - italic
- Link - link
- Size - size
- Strikethrough - strike
- Superscript/Subscript - script
- Underline - underline
Block
- Blockquote - blockquote
- Header - header
- Indent - indent
- List - list
- Text Alignment - align
- Text Direction - direction
- Code Block - code-block
Embeds
- Formula - formula (requires KaTex)
- Image - image
- Video - video
Quill usage props : value, onChange, placeholder
After seeing how we can customize our Quill editor, we will now see how we can use it in real life using three main props: value, onChange, placeholder.
Let’s return to our example and update it with these props :
import dynamic from 'next/dynamic'
import React, { useState } from "react";
import parse from 'html-react-parser';
const QuillNoSSRWrapper = dynamic(import('react-quill'), {
ssr: false,
loading: () => <p>Loading ...</p>,
})
const modules = {
toolbar: [
[{ header: '1' }, { header: '2' }, { font: [] }],
[{ size: [] }],
['bold', 'italic', 'underline', 'strike', 'blockquote'],
[
{ list: 'ordered' },
{ list: 'bullet' },
{ indent: '-1' },
{ indent: '+1' },
],
['link', 'image', 'video'],
['clean'],
],
clipboard: {
// toggle to add extra line breaks when pasting HTML:
matchVisual: false,
},
}
/*
* Quill editor formats
* See https://quilljs.com/docs/formats/
*/
const formats = [
'header',
'font',
'size',
'bold',
'italic',
'underline',
'strike',
'blockquote',
'list',
'bullet',
'indent',
'link',
'image',
'video',
]
export default function Home() {
const [value, setValue] = useState('');
return (
<div>
<QuillNoSSRWrapper modules={modules} placeholder='compose here' value={value} onChange={setValue} formats={formats} theme="snow" />
<p>{value}</p>
{parse(value)}
</div>
)}
placeholder
the placeholder is just what appears by default in our Quill component before we type anything in it , in our example the placeholder is ‘compose here ‘ , so the result is :
onChange
the onChange event executes a javascript whenever a change is occurring in our Quill component. In our case, onChange={setValue} , which means we will set the value property in our state with the current value in our editor
Final result
To show the result of our code, we selected the text to be H2, italic and underlined. You will see them toggled in blue in the toolbar :
the <p>{value}</p>
returns the content of value which is the html code as shown in the image : <h2><em><u>this is a test</u></em></h2>
.
to show the actual rendering, we use ‘html-react-parser’ to parse the html code.