Summernote is a JavaScript library that helps you create WYSIWYG editors with a simple and easy-to-use interface. Summernote is licensed under MIT and maintained by the community.
Homepage: https://summernote.org
Summernote has a few special features:
- Simple and User-friendly: Providing a simple and intuitive interface that allows users
- Easy to install: Just include the JS/CSS files on your HTML and create a div tag to get started.
- Compatible with Bootstrap: Bootstrap 3, 4, and 5.
- Rich ecosystem: A wide array of plugins and connectors are available, enhancing functionality and integration options.
- Easy image handling: Images are automatically embedded in the content using base64 encoding, eliminating the need for separate image management
- Horizontal Editor Resize: Drag the small handle on the left edge to change the editor width (min. 400px). Remaining space is applied as symmetric left/right margin. Disable via option
disableResizeHorizontal: true.
Summernote is built on jQuery.
Include the following code in the <head> tag of your HTML:
<!-- include libraries(jQuery, bootstrap) -->
<script type="text/javascript" src="//code.jquery.com/jquery-3.6.0.min.js"></script>
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" />
<script type="text/javascript" src="//cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"></script>
<!-- include summernote css/js-->
<link href="summernote-bs5.css" rel="stylesheet">
<script src="summernote-bs5.js"></script>Then place a div tag somewhere in the body tag. This element will be replaced with the summernote editor.
<div id="summernote">Hello Summernote</div>Finally, initialize Summernote with the following JavaScript:
$(document).ready(function() {
$('#summernote').summernote();
});For more examples, please visit to homepage.
Summernote provides a set of API. For example, you can use the following code to get the HTML source code underlying the text in the editor:
var html = $('#summernote').summernote('code');For more detail about API, please refer to document.
Warning - code injection The code view allows the user to enter script contents. Make sure to filter/sanitize the HTML on the server. Otherwise, an attacker can inject arbitrary JavaScript code into clients.
See the CONTRIBUTING.md for details on how to contribute to Summernote.
Thanks go to these incredible people:
Is your company using Summernote? Ask your boss to support us. It will help us dedicate more time to maintain this project and to make it even better for all our users. Also, your company logo will show up on here and on our website: -) [Become a sponsor]
Please be our Backers.
Configure serializableElements with custom-element tag names and provide
callbacks.onSerializeElement(element). The callback receives the live element
and returns a DOM node containing its authored representation, or null to retain
the current markup. Returned nodes should be created in an inert document to
avoid custom-element initialization. The callback must not mutate the live editor.
The editor serializes into an inert copy. Code view, the public code() getter,
save operations and undo snapshots all use this representation. The default empty
list preserves the original behavior. No component framework is required.
Configure atomicElements separately for inline components that must be selected as
indivisible objects. They receive a selection frame without resize handles. Arrow
keys move outside the selected component; clicks within the outer 4 px place the caret
before or after it (with a smaller zone for tiny components); Delete and Backspace remove it with undo
support. Temporary editability attributes are stripped during serialization.
The summernote.component.selected event receives the selected element for optional
application popovers. No component popover is included. Copy and cut serialize the selected range through
the same authored-node callback; paste also accepts HTML-only clipboard content.
Copies carry an instance-specific clipboard format. Pasting back into the same
editor preserves formatting without the external-content dialog. External content
continues through the configured paste sanitization. The insertion range is captured
before the dialog opens. Component fragments are imported into the active document
to ensure custom elements are upgraded when inserted. Clipboard fragment markers
are stripped and are not retained in code output.
Applications register additional tabs through emojiPickerTabs or
summernote('emoji.addTab', definition), before or after opening the picker.
Each definition has a unique id, a text label, an optional text icon, and
render(container, picker). The optional icon accepts text or a DOM element
(cloned for each tab button). Rendering runs once, on first activation. The picker
API exposes context, insertHtml(html) and close(). Insertion uses the saved
selection and closes the picker. Optional activate(container) runs on every tab selection, for example to focus
the search field. Optional destroy(container) releases resources.
The tab switch remains hidden until extra tabs exist. The Smartstore-style demo
registers a simple Symbols tab without an IconKit dependency.