Summernote - Super Simple WYSIWYG editor (2023)

Initialization options

Customize by Initializing various options and modules.

Custom toolbar, popover

Summernote allows you to customise the toolbar.

$('#summernote').summernote({ toolbar: [ // [groupName, [list of button]] ['style', ['bold', 'italic', 'underline', 'clear']], ['font', ['strikethrough', 'superscript', 'subscript']], ['fontsize', ['fontsize']], ['color', ['color']], ['para', ['ul', 'ol', 'paragraph']], ['height', ['height']] ]});

This is a toolbar with font style only.

You can compose a toolbar with pre-shipped buttons.

  • Insert
    • picture: open image dialog
    • link: open link dialog
    • video: open video dialog
    • table: insert a table
    • hr: insert a horizontal rule
  • Font Style
    • fontname: set font family
    • fontsize: set font size
    • fontsizeunit: set font size unit
    • color: set foreground and background color
    • forecolor: set foreground color
    • backcolor: set background color
    • bold: toggle font weight
    • italic: toggle italic
    • underline: toggle underline
    • strikethrough: toggle strikethrough
    • superscript: toggle superscript
    • subscript: toggle subscript
    • clear: clear font style
  • Paragraph style
    • style: format selected block
    • ol: toggle ordered list
    • ul: toggle unordered list
    • paragraph: dropdown for paragraph align
    • height: set line height
  • Misc
    • fullscreen: toggle fullscreen editing mode
    • codeview: toggle wysiwyg and html editing mode
    • undo: undo
    • redo: redo
    • help: open help dialog

The following settings are default options for toolbar buttons.

toolbar: [ ['style', ['style']], ['font', ['bold', 'underline', 'clear']], ['fontname', ['fontname']], ['color', ['color']], ['para', ['ul', 'ol', 'paragraph']], ['table', ['table']], ['insert', ['link', 'picture', 'video']], ['view', ['fullscreen', 'codeview', 'help']],],

Air-mode has its own popover, not toolbar. You can customize it with popover.air option.

$('#summernote').summernote({ popover: { air: [ ['color', ['color']], ['font', ['bold', 'underline', 'clear']] ] }});

You can also setup buttons of the other popovers in the same way. The below settings are default options for popovers.

popover: { image: [ ['image', ['resizeFull', 'resizeHalf', 'resizeQuarter', 'resizeNone']], ['float', ['floatLeft', 'floatRight', 'floatNone']], ['remove', ['removeMedia']] ], link: [ ['link', ['linkDialogShow', 'unlink']] ], table: [ ['add', ['addRowDown', 'addRowUp', 'addColLeft', 'addColRight']], ['delete', ['deleteRow', 'deleteCol', 'deleteTable']], ], air: [ ['color', ['color']], ['font', ['bold', 'underline', 'clear']], ['para', ['ul', 'paragraph']], ['table', ['table']], ['insert', ['link', 'picture']] ]}

Blockquote breaking level

You can set blockquote breaking level with blockquoteBreakingLevel option.

Each configurable breaking level means:

  • 0 - No break, the new paragraph remains inside the quote.
  • 1 - Break the first blockquote in the ancestors list.
  • 2 - Break all blockquotes, so that the new paragraph is not quoted. (default)
$('#summernote').summernote({ blockquoteBreakingLevel: 2});

Custom styles

You can set your own selection of styles with the styleTags option.

$('#summernote').summernote({ styleTags: [ 'p', { title: 'Blockquote', tag: 'blockquote', className: 'blockquote', value: 'blockquote' }, 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'], });

The tags can be specified just by tag name (as with p or pre or h1-h6 above). It is alsopossible to customize the style in more detail by providing an object looking like:

{ tag : 'tag name ', title : 'dropdown item title', style : 'dropdown item style', className : 'applyed element class name and dropdown item className', value : 'Value to apply when clicked'}

Custom fontNames

You can define fontNames items with the fontNames option.

$('#summernote').summernote({ fontNames: ['Arial', 'Arial Black', 'Comic Sans MS', 'Courier New']});

Summernote tests for fonts in fontNames before adding them to dropdown. This is a problem while using web fonts. It’s not easy picking a nice time to check the availability of web fonts. You can define a list of web fonts to be ignored with the fontNamesIgnoreCheck.

$('#summernote').summernote({ fontNames: ['Arial', 'Arial Black', 'Comic Sans MS', 'Courier New', 'Merriweather'], fontNamesIgnoreCheck: ['Merriweather']});

Summernote automatically populates the font dropdown with the available fonts that are given on fontNames option. This includes the font set on the current dom element. If you only want to display a specific list of fonts on the dropdown, you can set the addDefaultFonts option to false along with the fontNames option. Example settings below will only add Arial and Arial Black fonts to the dropdown.

$('#summernote').summernote({ fontNames: ['Arial', 'Arial Black'], addDefaultFonts: false});

Custom font size units

You can set the available font size units with the fontSizeUnits option.

$('#summernote').summernote({ fontSizeUnits: ['px', 'pt']});

Custom line heights

You can override the default list and specify a custom one.

$('#summernote').summernote({ lineHeights: ['0.2', '0.3', '0.4', '0.5', '0.6', '0.8', '1.0', '1.2', '1.4', '1.5', '2.0', '3.0']});

Custom placeholder

You can define a placeholder with the placeholder option.

$('#summernote').summernote({ placeholder: 'write here...'});

Summernote can also be set to inherit the placeholder from the placeholder attribute on the dom element.

<div class="summernote" placeholder="first placeholder"></div><div class="summernote" placeholder="second placeholder"></div>

And then set the inheritPlaceholder option as true during initialization.

$('.summernote').summernote({ inheritPlaceholder: true});


Dialogs can be placed in body, not within Summernote. If you’re using Summernote within a modal dialog, please set this option as true.

$('#summernote').summernote({ dialogsInBody: true});

By default, dialogs are shown and hidden without a fading effect. But you can turn it on by dialogsFade.

$('#summernote').summernote({ dialogsFade: true // Add fade effect on dialogs});

Disable drag and drop

You can disable drag and drop with the disableDragAndDrop option.

$('#summernote').summernote({ disableDragAndDrop: true});

Disable shortcuts

You can disable custom shortcuts with the shortcuts option.

$('#summernote').summernote({ shortcuts: false});

Disable TAB

You can disable TAB/Shift+Tab intereaction with the tabDisable option.This will allow tabbing through fields in Forms.

$('#summernote').summernote({ tabDisable: false});

XSS protection for CodeView

Summernote provides a XSS protection for CodeView. It consists of filtering tags and whitelist for iframe.

Whitelist filter is turned on by default, but filtering tags is not. You can turn them on and off by options like below.

$('#summernote').summernote({ codeviewFilter: false, codeviewIframeFilter: true});

And, you can also add your own whitelist domains and use custom tag filters. Please check the default filter before customizing.

$('#summernote').summernote({ codeviewFilterRegex: 'custom-regex', codeviewIframeWhitelistSrc: ['my-own-domainname']});

But you have to remember that this protection only affects on front-end side – to prevent attacks thoroughly, you have to check it on back-end side again.

Basic API

You can initialize Summernote with summernote.


Then You can use the editor API through the summernote method. This is an example code for inserting ‘hello world’ text.

$('#summernote').summernote('editor.insertText', 'hello world'));

It calls the editor module’s insertText method with ‘hello world’. The first argument is a string type which represents the module and its method. The rest are method’s arguments.

If you call the API without module name, editor.methodName will be called.

$('#summernote').summernote('insertText', 'hello world');

A module named editor supports several methods for editor’s basic behavior


You can toggle editable/codable view by API.



Creates a range object for current user selection.

var range = $('#summernote').summernote('createRange');

disable, enable

You can disable editor by API.


If you want to enable editor again, call API with enable.


Disable Spellchecking

You can disable Spellchecking in the Editing area with the spellCheck option.

$('#summernote').summernote({ spellCheck: true});

Disable Grammarly Browser Addon

You can disable the Grammarly Browser Addon (currently researching other Grammar Addons for their disabling options) by using the disableGrammar option.

$('#summernote').summernote({ disableGrammar: false});


Sets focus in current summernote



You can toggle Fullscreen view by API.



You can programmatically determine if the Summernote is in Fullscreen mode by using isFullscreen, which will return true or false.



You can find programmatically which Summernote you are using.This will return one of three values: bs3, bs4 or lite.



Returns whether editor content is empty or not.

The editing area needs <p><br></p> for focus, even if the editor content is empty. So Summernote supports this method for helping to check if editor content is empty.

if ($('#summernote').summernote('isEmpty')) { alert('editor content is empty');}


Clear the editor content and remove all stored history.


saveRange, restoreRange

saveRange saves current user selection internally.


restoreRange restores currently saved range

$('#summernote').summernote('saveRange');// move cursor and select another$('#summernote').summernote('restoreRange');

undo, redo

Undoes and Redoes the last command


Font style API

backColor, foreColor

Set the Background or Foreground color.

// @param {String} color$('#summernote').summernote('backColor', 'red');// @param {String} color$('#summernote').summernote('foreColor', 'blue');

bold, italic, underline, strikethrough

Set font style.



Set font family.

// @param {String} fontName$('#summernote').summernote('fontName', 'Arial');


Set font size.

// @param {Number} font size - unit is determined by selected font size unit.$('#summernote').summernote('fontSize', 20);


Set font size unit.

// @param {String} font size unit - defaults to px.$('#summernote').summernote('fontSizeUnit', 'pt');


Clean a style.


superscript, subscript

Set superscript or subscript.


Paragraph API


Change current paragraph as a <h1> ~ <h6>.



Change current paragraph as a <p>.


indent and outdent

Indent or Outdent on current paragraph.



Toggle ordered list or unordered list



Insert a paragraph


justify left, right and more

Set the alignment of a Paragraph.



Set line height.

// @param {Number} line height - unit is px$('#summernote').summernote('lineHeight', 20);

Insertion API

createLink, unlink

Create link and unlink.

// @param {String} text - link text// @param {String} url - link url// @param {Boolean} isNewWindow - whether link's target is new window or not$('#summernote').summernote('createLink', { text: "This is the Summernote's Official Site", url: '', isNewWindow: true});$('#summernote').summernote('unlink');


Insert an image.

// @param {String} url// @param {String|Function} filename - optional$('#summernote').summernote('insertImage', url, filename);

You can modify image with passing callback as second argument.

$('#summernote').summernote('insertImage', url, function ($image) { $image.css('width', $image.width() / 3); $image.attr('data-filename', 'retriever');});


Insert an element or textnode.

var node = document.createElement('div');// @param {Node} node$('#summernote').summernote('insertNode', node);


Insert text.

// @param {String} text$('#summernote').summernote('insertText', 'Hello, world');


Paste HTML string.

// @param {String} HTML stringvar HTMLstring = '<div><p>Hello, world</p><p>Summernote can insert HTML string</p></div>';$('#summernote').summernote('pasteHTML', HTMLstring);

Range & Selection API


refer to #saveRange


refer to #restorerange


summernote is saving a range object(WrappedRange) on current cursor.

const rng = $('#summernote').summernote('editor.getLastRange');

when summernote save a range with dom event

  • keydown
  • keyup
  • focus
  • mouseup
  • paste

when summernote save a range with api

  • editor.insertImage -> Image
  • editor.insertNode -> Node
  • editor.insertText -> TextNode
  • editor.pasteHTML -> last Node of contents
  • editor.insertHorizontalRule -> next sibling node of hr node
  • editor.createLink -> link node


You can define custom range in node of summernote editable element.

const range = $.summernote.range; // range utility// set my custom range$('#summernote').summernote('editor.setLastRange', range.createFromNodeAfter(node).select());

range utility

const range = $.summernote.range; // range utility

create WrappedRange Object

range utility make a WrappedRange Class’s instance


create WrappedRange Object From arguments or Browser Selection

const rng = range.create(startContainer, startOffset, endContainer, endOffset)// orconst rng = range.create() // is equals range.createFromSelection()

create WrappedRange object from node

const rng = range.createFromNode(node)

create WrappedRange from node before position

const rng = range.createFromNodeBefore(node)

create WrappedRange from node after position

const rng = range.createFromNodeAfter(node)

create WrappedRange object from selection

const rng = range.createFromSelection(node)

WrappedRange Object


select update visible range
const newRng = rng.collapse(true); // to start rng orconst newRng = rng.collapse(); // to end rng

splitText on range

const textRng = rng.splitText()

delete contents on range

const newRng = rng.deleteContents()

returns whether range was collapsed or not

const isCollapsed = rng.isCollapsed()

wrap inline nodes which children of body with paragraph

const newRng = rng.wrapBodyInlineWithPara()

insert node at current cursor

const node = rng.insertNode(document.createElement('div'))

insert html at current cursor

const nodes = rng.pasteHTML(`<div>summernote</div>`)

returns text in range


returns range for word before(or after) cursor

const newRng = rng.getWordRange(); // before cursor// orconst newRng = rng.getWordRange(true); // after cursor

returns range for words before cursor that match with a Regex

// range : 'hi @Peter Pan'const rng = range.create() // or $('.summernote').summernote('getLastRange');const newRng = rng.getWordsMatchRange(/@[a-z ]+/i)console.log(newRng.toString()) // '@Peter Pan'

returns a list of DOMRect objects representing the area of the screen occupied by the range.



Summernote support initialize callbacks and jquery’s custom event style callbacks.

Position of callbacks in options is changed after v0.7.0

After v0.7.0, every callbacks should be wrapped by callbacks object.

Callback only works with camel case string after v0.6.5

Lowercase string has been used for basic event name(ex: oninit, onenter, onfocus, onblur, onkeyup, onkeydown, onpaste). In contrast, callbacks name for advanced feature has been used with camel case string. This is inconsistent and confusing to use. So we rename all lowercase callback to camel case string.


WIP: Need to work on an explanation


  • IE9-10: DOMCharacterDataModified, DOMSubtreeModified, DOMNodeInserted
  • Chrome, FF: input
// onChange callback$('#summernote').summernote({ callbacks: { onChange: function(contents, $editable) { console.log('onChange:', contents, $editable); } }});// summernote.change$('#summernote').on('summernote.change', function(we, contents, $editable) { console.log('summernote\'s content is changed.');});


WIP: Need to work on an explanation


WIP: Need to work on an explanation


// onEnter callback$('#summernote').summernote({ callbacks: { onEnter: function() { console.log('Enter/Return key pressed'); } }});// summernote.enter$('#summernote').on('summernote.enter', function() { console.log('Enter/Return key pressed');});

onFocus, onBlur, onBlurCodeview

// onFocus callback$('#summernote').summernote({ callbacks: { onFocus: function() { console.log('Editable area is focused'); } }});// summernote.focus$('#summernote').on('summernote.focus', function() { console.log('Editable area is focused');});
// onBlur callback$('#summernote').summernote({ callbacks: { onBlur: function() { console.log('Editable area loses focus'); } }});// summernote.blur$('#summernote').on('summernote.blur', function() { console.log('Editable area loses focus');});
// onBlurCodeview callback$('#summernote').summernote({ callbacks: { onBlurCodeview: function() { console.log('Codeview area loses focus'); } }});// summernote.blur.codeview$('#summernote').on('summernote.blur.codeview', function() { console.log('Codeview area loses focus');});


Override insertion of image by url

// onImageLinkInsert callback$('#summernote').summernote({ callbacks: { onImageLinkInsert: function(url) { // url is the image url from the dialog $img = $('<img>').attr({ src: url }) $summernote.summernote('insertNode', $img[0]); } }});//$('#summernote').on('', function(we, url) { // url is the image url from the dialog $img = $('<img>').attr({ src: url }) $summernote.summernote('insertNode', $img[0]);});


Override image upload handler(default: base64 dataURL on IMG tag).You can upload image to server or AWS S3: more…

// onImageUpload callback$('#summernote').summernote({ callbacks: { onImageUpload: function(files) { // upload image to server and create imgNode... $summernote.summernote('insertNode', imgNode); } }});// summernote.image.upload$('#summernote').on('summernote.image.upload', function(we, files) { // upload image to server and create imgNode... $summernote.summernote('insertNode', imgNode);});


WIP: Need to work on an explanation


// onInit callback$('#summernote').summernote({ callbacks: { onInit: function() { console.log('Summernote is launched'); } }});// summernote.init$('#summernote').on('summernote.init', function() { console.log('Summernote is launched');});

onKeyup, onKeydown

// onKeyup callback$('#summernote').summernote({ callbacks: { onKeyup: function(e) { console.log('Key is released:', e.keyCode); } }});// summernote.keyup$('#summernote').on('summernote.keyup', function(we, e) { console.log('Key is released:', e.keyCode);});
// onKeydown callback$('#summernote').summernote({ callbacks: { onKeydown: function(e) { console.log('Key is downed:', e.keyCode); } }});// summernote.keydown$('#summernote').on('summernote.keydown', function(we, e) { console.log('Key is downed:', e.keyCode);});



// onPaste callback$('#summernote').summernote({ callbacks: { onPaste: function(e) { console.log('Called event paste'); } }});// summernote.paste$('#summernote').on('summernote.paste', function(e) { console.log('Called event paste');});


WIP: Need to work on an explanation

Custom button

Summernote also supports custom buttons. If you want to create your own button, you can simply define and use with options.

Define button

You can create a button object with $.summernote.ui. This buttons objects have the below properties.

  • contents: contents to be displayed on the button
  • tooltip: tooltip text when mouse over
  • click: callback function to be called when mouse is clicked

Below codes is about simple button for inserting text ‘hello’.

var HelloButton = function (context) { var ui = $.summernote.ui; // create button var button = ui.button({ contents: '<i class="fa fa-child"/> Hello', tooltip: 'hello', click: function () { // invoke insertText method with 'hello' on editor module. context.invoke('editor.insertText', 'hello'); } }); return button.render(); // return button as jquery object}

You can see render() which returns jquery object as button.

Using button with options

Let’s learn how to use the button on toolbar.

First, you can define buttons with option named buttons which is a set of key-value. You can define custom button on toolbar options.

$('.summernote').summernote({ toolbar: [ ['mybutton', ['hello']] ], buttons: { hello: HelloButton }});

You can also use custom button on popover in the same way.

Custom icons

Summernote supports the usage of your own custom icons. You can e.g. use SVG based icons instead of the default ones.

Define your own icons

If you want to override the default icons, configure summernote like this:

$('.summernote').summernote({ icons: { align: '<svg [...]>[...]</svg>', // [...] }});

Module system

For supporting expandable features, summernote was assembled by module system. This module system was built inspired by spring framework.

Key terms

  • Module: Module is a component.
  • Context: Context is a kind of container. It has modules and editor’s states.
  • Renderer: Renderer is a function for creating element.
  • UI: UI is a set of renderers to build ui elements.


Module is a component for implementing feature and it has lifecycle. Module also has helper methods or methods related with lifecycle.


This method will be called when editor is initialized by $(‘..’).summernote();. You can attach events and created elements on editor elements(eg, editable, …).

this.initialize = function () { // create button var button = ui.button({ className: 'note-btn-bold', contents: '<i class="fa fa-bold">', click: function (e) { context.invoke('editor.bold'); // invoke bold method of a module named editor } }); // generate jQuery element from button instance. this.$button = button.render(); $toolbar.append(this.$button);}


This method will be called when editor is destroyed by $(‘..’).summernote(‘destroy’); You should detach events and remove elements on initialize.

this.destroy = function () { this.$button.remove(); this.$button = null;}


This method is used for deciding whether module will be initialized or not.

// AirPopover's shouldInitializethis.shouldInitialize = function () { return options.airMode && !list.isEmpty(options.popover.air);};

Below are full codes of AutoLink module.

// Module Name is AutoLink// @param {Object} context - states of editorvar AutoLink = function (context) { // you can get current editor's elements from layoutInfo var layoutInfo = context.layoutInfo; var $editor = layoutInfo.editor; var $editable = layoutInfo.editable; var $toolbar = layoutInfo.toolbar; // ui is a set of renderers to build ui elements. var ui = $.summernote.ui; // this method will be called when editor is initialized by $('..').summernote(); // You can attach events and created elements on editor elements(eg, editable, ...). this.initialize = function () { // create button var button = ui.button({ className: 'note-btn-bold', contents: '<i class="fa fa-bold">', click: function (e) { // invoke bold method of a module named editor context.invoke('editor.bold'); } }); // generate jQuery element from button instance. this.$button = button.render(); $toolbar.append(this.$button); } // this method will be called when editor is destroyed by $('..').summernote('destroy'); // You should detach events and remove elements on `initialize`. this.destroy = function () { this.$button.remove(); this.$button = null; }};

For more module examples: modules

Module with options

You can define custom module with options.

$(".summernote").summernote({ modules: { myModule: MyModule }});

You can called module’s method with external API.

$(".summernote").summernote("myModule.method", 'hello');


Plugin is a kind of external module. You can also define your own module with plugin.

// src/mymodule.js$.extend($.summernote.plugins, { myModule: function (context) { // define module ... }});

Below link is a example of external module.

Plugin was redesigned by new module system after v0.7.0

Old plugin was hard to control editor states(eg, range, layout so on). After v0.7.0 plugin is redesigned by new module system. It is exactly same with module except surrounding module pattern.


Notification / Information Area

Summernote allows to add Notifications with Contextual Colouring to indicate the type of Notifcation, or to use the area for Informational Purposes.

The area appears at the bottom of Summernote when used in Normal Mode, and at the top of the editing area when Summernote is used in Air Mode.

To use the Notifcation area is simple and is useable by targetting the area using it’s class name .note-status-output.

Notification elements can use any markup, but we’ve added some styling along the lines of Bootstrap’s Alerts. For e.g. to produce an Error or Danger alert you can use <div class="alert alert-danger">This is an error</div>. You can also use alert-info, alert-warning, alert-success and alert-danger.

You can add the above message using jQuery or other Javascript method by targetting the output element, like (using jQuery):

$('.note-status-output').html( '<div class="alert alert-danger">' + 'This is an error using a Bootstrap alert that has been restyled to fit here.' + '</div>');

If you want to display just Informational Text, you can also add Text without the Alert if you wish.

$('.note-status-output').html( 'Text Information');

You can also place text to the right side by placing the Text within an element such as div, span or small and including the class .pull-right.

You can also use Contextual Colours for your text using the classes text-muted, text-primary, ‘text-success’, text-info, text-warning and text-danger.

Top Articles
Latest Posts
Article information

Author: Twana Towne Ret

Last Updated: 02/21/2023

Views: 6179

Rating: 4.3 / 5 (64 voted)

Reviews: 87% of readers found this page helpful

Author information

Name: Twana Towne Ret

Birthday: 1994-03-19

Address: Apt. 990 97439 Corwin Motorway, Port Eliseoburgh, NM 99144-2618

Phone: +5958753152963

Job: National Specialist

Hobby: Kayaking, Photography, Skydiving, Embroidery, Leather crafting, Orienteering, Cooking

Introduction: My name is Twana Towne Ret, I am a famous, talented, joyous, perfect, powerful, inquisitive, lovely person who loves writing and wants to share my knowledge and understanding with you.