Trumbowyg.js: Lightweight WYSIWYG Editor Plugin For jQuery
| File Size: | 202 KB |
|---|---|
| Views Total: | 32957 |
| Last Update: | |
| Publish Date: | |
| Official Website: | Go to website |
| License: | MIT |
Trumbowyg is a lightweight jQuery WYSIWYG rich text editor that turns a textarea or editable container into a configurable HTML editor with formatting controls, semantic markup, localization, plugins, and a jQuery API.
It's great for CMS fields, admin panels, comment forms, and other UIs that need visual HTML editing inside an existing jQuery project.
Features
- Configurable WYSIWYG toolbar with HTML source view, formatting, links, images, lists, alignment, and fullscreen mode.
- Semantic HTML conversion with configurable tag handling and tag-specific CSS classes.
- Plugin system for colors, fonts, tables, uploads, media embeds, image resizing, mentions, paste handling, and more.
- More than 45 localization files, with English built into the core editor.
- SVG editor icons with configurable sprite paths and support for custom skins.
- jQuery API for reading and writing HTML, managing selections, opening modals, changing editor state, and destroying an instance.
- Editor events for initialization, focus, blur, content changes, paste, resize, fullscreen mode, and modal lifecycle.
Alternatives And Related Resources
- 10 Best WYSIWYG Editors For Easier Content Editing
- Summernote: jQuery WYSIWYG Editor for Bootstrap 5
- Minimal Rich Text Editor With jQuery And FontAwesome - RichText
Installation
Install Trumbowyg with npm, or download the distribution files and load them directly in the browser.
# npm npm install trumbowyg
Trumbowyg requires jQuery 1.8 or newer. Load the editor stylesheet, jQuery, and Trumbowyg in this order.
<link rel="stylesheet" href="trumbowyg/dist/ui/trumbowyg.min.css"> <script src="jquery.min.js"></script> <script src="trumbowyg/dist/trumbowyg.min.js"></script>
How To Use Trumbowyg
Basic Setup
Add a textarea or container for the editor.
<textarea id="editor" name="content"></textarea>
Initialize Trumbowyg after jQuery and the editor script have loaded.
$('#editor').trumbowyg();
Use A Custom Toolbar
The btns option controls the toolbar groups and button order.
$('#editor').trumbowyg({
btns: [
['viewHTML'],
['undo', 'redo'],
['formatting'],
['strong', 'em'],
['link'],
['insertImage'],
['unorderedList', 'orderedList'],
['fullscreen']
],
autogrow: true
});
Load A Language Pack
English is included in the core editor. For another language, load its file after Trumbowyg and before initialization, then set lang.
<script src="trumbowyg/dist/langs/fr.min.js"></script>
$('#editor').trumbowyg({
lang: 'fr'
});
Load A Plugin
Load plugin JavaScript after jQuery and Trumbowyg, but before the initialization code. Plugins with their own UI styles also require the matching CSS file.
<link rel="stylesheet" href="trumbowyg/dist/plugins/colors/ui/trumbowyg.colors.min.css"> <script src="jquery.min.js"></script> <script src="trumbowyg/dist/trumbowyg.min.js"></script> <script src="trumbowyg/dist/plugins/colors/trumbowyg.colors.min.js"></script>
$('#editor').trumbowyg({
btns: [
['strong', 'em'],
['foreColor', 'backColor']
]
});
Bundled Plugins
Trumbowyg currently includes 27 bundled plugins. Some plugins register behavior as soon as their script loads. Button-based plugins also need their button name in the btns configuration.
- Allow Tags From Paste: Keeps selected HTML tags when users paste formatted content.
- Base 64: Inserts images as base64 data.
- Clean Paste: Cleans pasted HTML before insertion.
- Colors: Adds foreground and background color controls.
- Emoji: Adds an emoji picker.
- Font Family: Adds a font-family selector.
- Font Size: Adds a font-size selector.
- Giphy: Searches for and inserts GIFs from Giphy.
- Highlight: Adds code highlighting support.
- History: Adds history-based undo and redo buttons.
- Indent: Adds indent and outdent controls.
- Insert Audio: Inserts HTML audio content.
- Line Height: Adds a line-height selector.
- MathML: Adds MathML editing support.
- Mention: Inserts users from a configurable source list.
- Noembed: Embeds supported content from a URL through noembed.com.
- Paste Embed: Converts pasted supported URLs into embedded content.
- Paste Image: Inserts clipboard images as base64 data.
- Preformatted: Wraps code content in preformatted markup.
- Resizimg: Adds drag handles for image resizing. This plugin also requires jquery-resizable.
- Ruby: Adds ruby text markup controls.
- Special Chars: Adds a special-character picker.
- Speech Recognition: Inserts text from browser speech recognition.
- Table: Creates and manages tables, rows, columns, cell merging, and table colors.
- Template: Inserts predefined HTML templates.
- Tenor: Searches for and inserts GIFs from Tenor.
- Upload: Uploads an image to a server and inserts the returned URL into the editor.
Core Configuration Options
$('#editor').trumbowyg({
lang: 'en',
fixedBtnPane: false,
fixedFullWidth: false,
autogrow: false,
autogrowOnEnter: false,
imageWidthModalEdit: false,
hideButtonTexts: null,
prefix: 'trumbowyg-',
tagClasses: {},
semantic: true,
semanticKeepAttributes: false,
resetCss: false,
removeformatPasted: false,
tabToIndent: false,
tagsToRemove: [],
tagsToKeep: ['hr', 'img', 'embed', 'iframe', 'input'],
btns: [
['viewHTML'],
['undo', 'redo'],
['formatting'],
['strong', 'em', 'del'],
['superscript', 'subscript'],
['link'],
['insertImage'],
['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],
['unorderedList', 'orderedList'],
['horizontalRule'],
['removeformat'],
['fullscreen']
],
btnsDef: {},
changeActiveDropdownIcon: false,
inlineElementsSelector: 'a,abbr,acronym,b,caption,cite,code,col,dfn,dir,dt,dd,em,font,hr,i,kbd,li,q,span,strikeout,strong,sub,sup,u',
pasteHandlers: [],
plugins: {},
urlProtocol: false,
minimalLinks: false,
linkTargets: ['_self', '_blank'],
svgPath: null
});
URL Protocol
urlProtocol controls how Trumbowyg handles links that do not already include a protocol. The default value is false. Set it to true to prefix bare domains with https://, or pass a protocol string such as 'ftp'.
$('#editor').trumbowyg({
urlProtocol: true
});
For example, example.com becomes https://example.com. Anchor links, email addresses, and relative URLs are left unchanged.
Link Targets
linkTargets controls the target choices shown for links. The first entry is the default target. Current defaults are ['_self', '_blank'].
$('#editor').trumbowyg({
linkTargets: ['_blank', '_self', '_parent', '_top']
});
Older Trumbowyg releases used defaultLinkTarget. Current configurations should use linkTargets.
Minimal Link Dialog
Set minimalLinks to true to keep only the URL and text fields in the link dialog.
$('#editor').trumbowyg({
minimalLinks: true
});
Tag Classes
The tagClasses option assigns CSS classes to generated tags.
$('#editor').trumbowyg({
tagClasses: {
h2: 'content-heading',
blockquote: 'content-quote',
table: 'content-table'
}
});
Plugin Configuration Reference
The following settings cover the plugin configuration already used on this page. Plugins that expose no configuration only need their script and, when applicable, a toolbar button.
// Allow Tags From Paste // When empty, all tags are allowed making this plugin useless // If you want to remove all tags, use removeformatPasted core option instead allowedTags: [], // List of tags which can be allowed removableTags: [ 'a', 'abbr', 'address', 'b', 'bdi', 'bdo', 'blockquote', 'br', 'cite', 'code', 'del', 'dfn', 'details', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'ins', 'kbd', 'mark', 'meter', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'small', 'span', 'strong', 'sub', 'summary', 'sup', 'time', 'u', 'var', 'wbr', 'img', 'map', 'area', 'canvas', 'figcaption', 'figure', 'picture', 'audio', 'source', 'track', 'video', 'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'table', 'caption', 'th', 'tr', 'td', 'thead', 'tbody', 'tfoot', 'col', 'colgroup', 'style', 'div', 'p', 'form', 'input', 'textarea', 'button', 'select', 'optgroup', 'option', 'label', 'fieldset', 'legend', 'datalist', 'keygen', 'output', 'iframe', 'link', 'nav', 'header', 'hgroup', 'footer', 'main', 'section', 'article', 'aside', 'dialog', 'script', 'noscript', 'embed', 'object', 'param' ] // Colors colorList: [ 'ffffff', '000000', 'eeece1', '1f497d', '4f81bd', 'c0504d', '9bbb59', '8064a2', '4bacc6', 'f79646', 'ffff00', 'f2f2f2', '7f7f7f', 'ddd9c3', 'c6d9f0', 'dbe5f1', 'f2dcdb', 'ebf1dd', 'e5e0ec', 'dbeef3', 'fdeada', 'fff2ca', 'd8d8d8', '595959', 'c4bd97', '8db3e2', 'b8cce4', 'e5b9b7', 'd7e3bc', 'ccc1d9', 'b7dde8', 'fbd5b5', 'ffe694', 'bfbfbf', '3f3f3f', '938953', '548dd4', '95b3d7', 'd99694', 'c3d69b', 'b2a2c7', 'b7dde8', 'fac08f', 'f2c314', 'a5a5a5', '262626', '494429', '17365d', '366092', '953734', '76923c', '5f497a', '92cddc', 'e36c09', 'c09100', '7f7f7f', '0c0c0c', '1d1b10', '0f243e', '244061', '632423', '4f6128', '3f3151', '31859b', '974806', '7f6000' ], foreColorList: null, // fallbacks on colorList backColorList: null, // fallbacks on colorList allowCustomForeColor: true, allowCustomBackColor: true, displayAsList: false, // Font Family fontList: [ {name: 'Arial', family: 'Arial, Helvetica, sans-serif'}, {name: 'Arial Black', family: 'Arial Black, Gadget, sans-serif'}, {name: 'Comic Sans', family: 'Comic Sans MS, Textile, cursive, sans-serif'}, {name: 'Courier New', family: 'Courier New, Courier, monospace'}, {name: 'Georgia', family: 'Georgia, serif'}, {name: 'Impact', family: 'Impact, Charcoal, sans-serif'}, {name: 'Lucida Console', family: 'Lucida Console, Monaco, monospace'}, {name: 'Lucida Sans', family: 'Lucida Sans Uncide, Lucida Grande, sans-serif'}, {name: 'Palatino', family: 'Palatino Linotype, Book Antiqua, Palatino, serif'}, {name: 'Tahoma', family: 'Tahoma, Geneva, sans-serif'}, {name: 'Times New Roman', family: 'Times New Roman, Times, serif'}, {name: 'Trebuchet', family: 'Trebuchet MS, Helvetica, sans-serif'}, {name: 'Verdana', family: 'Verdana, Geneva, sans-serif'} ] // Font Size sizeList: [ 'x-small', 'small', 'medium', 'large', 'x-large' ], allowCustomSize: true // Giphy { rating: 'g', apiKey: null, throttleDelay: 300, noResultGifUrl: 'https://media.giphy.com/media/2Faz9FbRzmwxY0pZS/giphy.gif' }; // Insert Audio src: { label: 'URL', required: true }, autoplay: { label: 'AutoPlay', required: false, type: 'checkbox' }, muted: { label: 'Muted', required: false, type: 'checkbox' }, preload: { label: 'preload options', required: false } // Line Height sizeList: [ '0.9', 'normal', '1.5', '2.0' ] // Mention source: [], formatDropdownItem: formatDropdownItem, formatResult: formatResult // Noembed proxy: 'https://noembed.com/embed?nowrap=on', urlFiled: 'url', data: [], success: undefined, error: undefined // Paste Embed enabled: true, endpoints: [ 'https://noembed.com/embed?nowrap=on', 'https://api.maxmade.nl/url2iframe/embed' ] // Resizimg minSize: 32, step: 4, // Special Chars symbolList: [ // currencies '0024', '20AC', '00A3', '00A2', '00A5', '00A4', '2030', null, // legal signs '00A9', '00AE', '2122', null, // textual sign '00A7', '00B6', '00C6', '00E6', '0152', '0153', null, '2022', '25CF', '2023', '25B6', '2B29', '25C6', null, //maths '00B1', '00D7', '00F7', '21D2', '21D4', '220F', '2211', '2243', '2264', '2265' ] // Table rows: 8, columns: 8, allowHorizontalResize: true, colorList: [ 'ffffff', '000000', 'eeece1', '1f497d', '4f81bd', 'c0504d', '9bbb59', '8064a2', '4bacc6', 'f79646', 'ffff00', 'f2f2f2', '7f7f7f', 'ddd9c3', 'c6d9f0', 'dbe5f1', 'f2dcdb', 'ebf1dd', 'e5e0ec', 'dbeef3', 'fdeada', 'fff2ca', 'd8d8d8', '595959', 'c4bd97', '8db3e2', 'b8cce4', 'e5b9b7', 'd7e3bc', 'ccc1d9', 'b7dde8', 'fbd5b5', 'ffe694', 'bfbfbf', '3f3f3f', '938953', '548dd4', '95b3d7', 'd99694', 'c3d69b', 'b2a2c7', 'b7dde8', 'fac08f', 'f2c314', 'a5a5a5', '262626', '494429', '17365d', '366092', '953734', '76923c', '5f497a', '92cddc', 'e36c09', 'c09100', '7f7f7f', '0c0c0c', '1d1b10', '0f243e', '244061', '632423', '4f6128', '3f3151', '31859b', '974806', '7f6000' ], backgroundColorList: null, // fallbacks on colorList allowCustomBackgroundColor: true, displayBackgroundColorsAsList: false, borderColorList: null, // fallbacks on colorList allowCustomBorderColor: true, displayBorderColorsAsList: false, dropdown: [ { title: 'tableRows', buttons: [ 'tableAddHeaderRow', 'tableAddRowAbove', 'tableAddRow', 'tableDeleteRow', ], }, { title: 'tableColumns', buttons: [ 'tableAddColumnLeft', 'tableAddColumn', 'tableDeleteColumn', ], }, { title: 'tableVerticalAlign', buttons: [ 'tableVerticalAlignTop', 'tableVerticalAlignMiddle', 'tableVerticalAlignBottom', ], }, { title: 'tableOthers', buttons: [ // Cell merge/split 'tableMergeCells', 'tableUnmergeCells', 'tableDestroy', ] } ], // Upload serverPath: '', fileFieldName: 'fileToUpload', data: [], // Additional data for ajax [{name: 'key', value: 'value'}] headers: {}, // Additional headers xhrFields: {}, // Additional fields urlPropertyName: 'file', // How to get url from the json response (for instance 'url' for {url: ....}) statusPropertyName: 'success', // How to get status from the json response success: undefined, // Success callback: function (data, trumbowyg, $modal, values) {} error: undefined, // Error callback: function () {} imageWidthModalEdit: false // Add ability to edit image width
Speech Recognition
$('#editor').trumbowyg({
btns: [
['speechrecognition']
],
plugins: {
speechrecognition: {
lang: 'en-GB'
}
}
});
API Methods
// Open a modal.
var $modal = $('#editor').trumbowyg('openModal', {
title: 'Editor Settings',
content: 'Custom modal content
'
});
// Close the current modal.
$('#editor').trumbowyg('closeModal');
// Build a modal from input definitions.
$('#editor').trumbowyg('openModalInsert', {
title: 'Insert Link Data',
fields: {
url: {
label: 'URL',
required: true
}
},
callback: function (values) {
console.log(values.url);
return true;
}
});
// Save and restore the current selection range.
$('#editor').trumbowyg('saveRange');
$('#editor').trumbowyg('restoreRange');
// Get the current range.
var range = $('#editor').trumbowyg('getRange');
// Get text from the last saved range.
var selectedText = $('#editor').trumbowyg('getRangeText');
// Get editor HTML.
var content = $('#editor').trumbowyg('html');
// Replace editor HTML.
$('#editor').trumbowyg('html', 'Updated content
');
// Remove all editor content.
$('#editor').trumbowyg('empty');
// Disable or enable editing.
$('#editor').trumbowyg('disable');
$('#editor').trumbowyg('enable');
// Toggle HTML and WYSIWYG views.
$('#editor').trumbowyg('toggle');
// Destroy the editor and restore the original element.
$('#editor').trumbowyg('destroy');
Events
Trumbowyg triggers editor events on the jQuery element used to create the editor.
$('#editor')
.trumbowyg()
.on('tbwfocus', function () {
// Editor received focus.
})
.on('tbwblur', function () {
// Editor lost focus.
})
.on('tbwinit', function () {
// Editor initialized.
})
.on('tbwchange', function () {
// Editor content changed.
})
.on('tbwresize', function () {
// Autogrow changed the editor size.
})
.on('tbwpaste', function () {
// Content was pasted.
})
.on('tbwopenfullscreen', function () {
// Fullscreen mode opened.
})
.on('tbwclosefullscreen', function () {
// Fullscreen mode closed.
})
.on('tbwclose', function () {
// Editor closed.
})
.on('tbwmodalopen', function () {
// A Trumbowyg modal opened.
})
.on('tbwmodalclose', function () {
// A Trumbowyg modal closed.
});
Advanced Examples
Get And Save HTML Content
Use the html method as a getter before sending editor content through your existing form or AJAX workflow.
$('#save-post').on('click', function () {
var htmlContent = $('#editor').trumbowyg('html');
$('#content-field').val(htmlContent);
});
Clean Pasted Content
The core removeformatPasted option strips formatting from pasted content. The Clean Paste plugin provides a separate cleanup path for pasted HTML.
$('#editor').trumbowyg({
removeformatPasted: true
});
Add Image Upload
The Upload plugin sends the selected image to your server and expects a JSON response that contains the uploaded file URL.
$('#editor').trumbowyg({
btns: [
['strong', 'em'],
['upload']
],
plugins: {
upload: {
serverPath: '/uploads/editor-image',
fileFieldName: 'fileToUpload',
urlPropertyName: 'file',
statusPropertyName: 'success'
}
}
});
FAQs
Q: How do I add https:// to links that users enter without a protocol?
A: Set urlProtocol: true. Trumbowyg then prefixes bare domains with https://. You can also pass a custom protocol string.
Q: What replaced defaultLinkTarget?
A: Use linkTargets. The first item in the array acts as the default target, and the current default list is ['_self', '_blank'].
Q: How do I get or replace the editor HTML?
A: Call $('#editor').trumbowyg('html') to read the HTML. Pass HTML as the second argument to replace the current content.
Q: Why do Trumbowyg SVG icons fail to load?
A: Check the SVG asset path and cross-origin requests first. Trumbowyg can also use a custom svgPath when the automatic sprite path does not match your asset layout.
Changelog:
v2.31.0 (2025-03-03)
- Make icons hidden without importing trumbowyg.css
- Fix tagClasses to make it work in any cases
- Fix modal select by adding/fixing id and name
- Fix modal close when pressing Escape
v2.30.0 (2025-01-30)
- Adjust style to be compatible with 2 latest versions of each browser or usage > 1%
- Upgrade SCSS files to match the latest version
- New Speech Recognition plugin
- New Tenor plugin
- New Giphy plugin
v2.29.0 (2025-01-29)
- Bugfix for Table plugin
v2.28.0 (2023-03-07)
- Bugfix
v2.27.3 (2023-03-01)
- Bugfix
v2.27.0/1/2 (2023-02-28)
- Table plugin rework
- Feat: change editor HTML structure to allow overlays
- Feat: add .trumbowyg-icons class for plugin SVG Sprites
- Upgrade: use Array.isArray instead of deprecated $.isArray
- Add Azerbaijani support
- Update Catalan and Spanish core and plugins translations
- Bugfixes
v2.26.0 (2022-11-15)
- Breaking Change: Replace defaultLinkTarget option with linkTargets list
- Feat: Add the ability to create select in modal
- Feat: Add a select to pick the link target in the insert link modal
- Bugfixes
v2.25.2 (2022-08-12)
- Add Russian translations to all plugin
- Add Belarusian translations to all plugin
- Fix: do not disable removeformatPasted when the plugin is disabled itself
- Prevent Firefox from nesting multiple spans on font-size changes
- Fixes "Cannot read property '1' of null"
- Make MathML editable, even after toggle HTML view
v2.25.1 (2021-07-15)
- Prevent error when range does not exist
v2.25.0 (2021-07-05)
- Fixed: Disable buttons when the editor is disabled
v2.24.0 (2021-06-08)
- Fixed: Disable buttons when the editor is disabled
- Add Estonian support
- Add Bangla support
- Add Spanish translations to table plugin
- Add Turkish translations to some plugins
- Plugins update
v2.23.0 (2020-12-07)
- Add tagClasses option to add classes to any tag
- Add Plugin indent: button indent & outdent
v2.22.0 (2020-11-26)
- Lot of fixes
v2.21.0 (2019-12-31)
- Properly clean body events on destroy
- Add resize handle with canvas
v2.20.0 (2019-11-05)
- Add tbwmodalopen and tbwmodalclose events
- Add defaultLinkTarget option
- Fixed Wrap cursor in p when empty
- Add throttleDelay option and noResultGifUrl option to Giphy plugin
v2.19.0 (2019-09-02)
- Set list-style decimal for ordoned lists in resetCss
- Avoid 1px move on editor switch
- Disable word wrapping in dropdowns
- Restore close modal on escape
- Add missing skipTrumbowyg to execCmd API binding
- Fix Thai key from de to th
- Add Add row above and change Add columns to Add columns to the left/right
- Fix Font family bug when selecting a font with a space in the name
- Fix color minification issue by using rgba instead of HEX+alpha
This awesome jQuery plugin is developed by Alex-D. For more Advanced Usages, please check the demo page or visit the official website.











