Get started


Via a package manager
npm install trumbowyg bower install trumbowyg
Download the package

If you don't already do it, load jQuery at bottom of <body> like so:

<script src="//"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-3.3.1.min.js"><\/script>')</script>

Trumbowyg requires jQuery >= 1.8

After these lines, you have to load Trumbowyg.

<script src="trumbowyg/dist/trumbowyg.min.js"></script>

Don't forget to load Trumbowyg CSS in the <head>, or load your own style for the editor.

<link rel="stylesheet" href="trumbowyg/dist/ui/trumbowyg.min.css">


This the minimal code to transform a simple div into the amazing WYSIWYG editor which is Trumbowyg.


If you want to set options to Trumbowyg, add an object which contains your options as parameters.

    btns: [['strong', 'em',], ['insertImage']],
    autogrow: true

Common issues

SVG icons does not load

  • check if you are in HTTP(S) protocol;
  • check if you do not have cross domain error (XHR request is used).

If your problem is not solved by these tips, check the SVG icons section.

Use plugins

Add a plugin to your page

Basically you need to add the plugin JS to your page, at the bottom of your <body>, after jQuery and Trumbowyg imports (in this order), but before your custom JS which initialize Trumbowyg:

<!-- Import jQuery -->
<script src="//"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-3.3.1.min.js"><\/script>')</script>

<!-- Import Trumbowyg -->
<script src="trumbowyg/dist/trumbowyg.min.js"></script>

<!-- Import Trumbowyg plugins... -->
<script src="trumbowyg/dist/plugins/upload/trumbowyg.cleanpaste.min.js"></script>
<script src="trumbowyg/dist/plugins/upload/trumbowyg.pasteimage.min.js"></script>

<!-- Init Trumbowyg -->
    // Doing this in a loaded JS file is better, I put this here for simplicity

In the previous case, plugins are "auto registering" themself into Trumbowyg and be activated in all future Trumbowyg instances.

But most popular plugins are button-based, like upload or colors ones. If you want to use these plugins, load them like explained before, then add the plugin button to your editor by checking the button pane doc section.

For more information on plugins, check the plugins documentation page.



You can change prefix of all class added on elements of Trumbowyg using this option:

    prefix: 'custom-prefix'

For example, the bold button class is now custom-prefix-bold-button

Default value is trumbowyg


Your users don't speak english? No problem, Trumbowyg has a language parameter. You have to load the appropriate lang file. Search in /dist/langs folder to see if a language file already exists, if not create it and share it :). See add a localization for more details on language file.

Don't forget include the lang file in your pages:

<script type="text/javascript" src="js/dist/langs/fr.min.js"></script>

Warning, include lang file after Trumbowyg and before instantiating the editor!

Usage of language parameter:

    lang: 'fr'

If the lang was not found, english values are used by default.

Custom skin

Trumbowyg is flexible and simple. You want a different look?

Replace existing CSS file

Copy /src/ui/ folder somewhere and customize style. Finally, link your new CSS file and remove link to Trumbowyg default style.

It is not recommended to directly edit the CSS file in the trumbowyg folder. When you update the plugin, your modifications will be erased.

Multiple skins for multiple Trumbowyg

This is useful when you do not want same design for all instances of Trumbowyg.

Use the prefix option:

    prefix: 'modern-ui'

In your CSS, you can now stylize .modern-ui-link-button for example, whitout conflicts with the default skin. It's necessary to redefine style for all elements. If you want to start from the default skin, copy /src/ui/ folder, replace all trumbowyg- by your prefix and work from here.

SVG icons

Added in 2.1.0

A pack of SVG icons is available and enabled by default. This file is loaded via XHR request in JavaScript so it is possible the path is not matching with your assets file paths. You can change the path of the SVG or disable this feature.

Change SVG path globally

To change SVG path, you need to set the path in global Trumbowyg configuration object:

$.trumbowyg.svgPath = '/assets/my-custom-path/icons.svg';

This global way needs to be done before initialize any Trumbowyg instance.

Disable SVG icons globally

If you do not want SVG icons, you can set this option to false. Then, you can add your custom icons by CSS or what you want.

$.trumbowyg.svgPath = false;

Check hide button texts option if you did not want button content at all and customize it by yourself.

This global way needs to be done before initialize any Trumbowyg instance.

Change SVG path or disable SVG icons locally

You can also apply svgPath option for an isolated editor only.

    svgPath: false // or a path like '/assets/my-custom-path/icons.svg'

Use absolute path to SVG sprite

Added in 2.22.0

If you want to be IE-complient you should use this option.

This will load icons directly from the sprite file. Instead of loading the sprite inline into the page, you can directly set this global option to true.

$.trumbowyg.svgAbsoluteUsePath = true;

This option is useful to avoid issues with baseURL.

This global way needs to be done before initialize any Trumbowyg instance.

Default value for svgAbsoluteUsePath is false.

Use SVG icons without XHR or via an another protocol than HTTP(S)

If you want to be IE9-complient you should use this option.

If you do not want use HTTP(S) protocol or use XHR to load icons, you can load icons in your HTML on your own. You just need to include the icons.svg file inline in your <body>:

<div id="trumbowyg-icons">
    <svg xmlns="">
        <symbol id="trumbowyg-blockquote" viewBox="0 0 72 72"><path d="..."></path></symbol>
        <symbol id="trumbowyg-bold" viewBox="0 0 72 72"><path d="..."></path></symbol>
        <symbol id="trumbowyg-close" viewBox="0 0 72 72"><path d="..."></path></symbol>
        <!-- ... all other icons here -->

You need to use this id: <prefix>-icons.

Trumbowyg checks if a #<prefix>-icons exists. If not, it loads SVG icons file via XHR and puts it in a div with this id. Next editor on the page does not load icons again. By adding this div in the page, you "hack" this mechanism to load it on your own.


Like the HTML5 attribute on input and textarea, you can add a placeholder with Trumbowyg.

<div class="my-editor" placeholder="Your text as placeholder"></div>

Placeholder is visible only if the element is empty (no HTML/text).

Placeholder is both managed in JS and CSS with the default style. If you create your own style, you need to apply the following style (replace trumbowyg by your prefix):

    content: attr(placeholder);
    color: #999;


Added in 2.1.0

Trumbowyg supports disabled attribute on a textarea and an option.

<textarea class="my-editor" disabled></textarea>

    disabled: true

You can switch between disabled and enabled states by using API

Basic Options

Button pane

It's probably the most interesting option, it allows you to choose the buttons that appears in the button pane. This option is an array containing string values representing the buttons or vertical separators (using the pipe character). To create your own custom button pane, define an array and pass it to the btns option.

    btns: [['bold', 'italic'], ['link']]

By default, btns option value is:

    btns: [
        ['undo', 'redo'], // Only supported in Blink browsers
        ['strong', 'em', 'del'],
        ['superscript', 'subscript'],
        ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],
        ['unorderedList', 'orderedList'],

Active dropdown icon

Added in 2.18.0

Dropdown icon can change to the active sub-button icon with this option enabled.

    changeActiveDropdownIcon: true

By default, changeActiveDropdownIcon option value is: false

Hide button texts

Added in 2.5.0

You can hide button texts showed when you put svgPath to false.

// Globally
$.trumbowyg.hideButtonTexts = true

// Or locally
    hideButtonTexts: true

If you disable SVG icons and button texts, you should design them by yourself.


Generates a better, more semantic oriented HTML (i.e. <em> instead of <i>, <strong> instead of <b>, etc.). It's just a boolean:

    semantic: false

Enabling semantic mode deactivates the underline button by default because they do not convey any real semantic. If you want to reactivate them, you have to do it explicitly, see Button pane

Since 2.12.0 you can also put an object to customize the semantic tag mapping for each one of these tags: <b>, <i>, <s>, <strike>, <div>.

    semantic: {
        'div': 'div' // Editor does nothing on div tags now

This option is set to true by default which is equivalent to:

    semantic: {
        'b': 'strong',
        'i': 'em',
        's': 'del',
        'strike': 'del',
        'div': 'p'

Reset CSS

If you don't want the page style to impact on the look of the text in the editor, you will need to apply a reset-css on the editor. You can activate this with the resetCss option:

    resetCss: true

This option is set to false by default. The reset only applies to the editor, not to the generated HTML code.

Remove format pasted

If you don't want styles pasted from clipboard (from Word or other webpage for example), pass the removeformatPasted option to true

    removeformatPasted: true

In order to use this option, you need to define a font size in your CSS or use a reset like normalize.

Remove format pasted is not active by default (set to false).

Tags to remove

Allow to sanitize the code by removing all tags you want. The tagsToRemove option is an array.

    tagsToRemove: ['script', 'link']

You must do the sanitize server-side too to avoid some security issues like XSS.

Tags to remove is an empty array by default (set to []).

Tags to keep

Added in 2.12.0

Sometimes you want to keep some empty i tags for Font Awesome or anything else. You can define this list via the tagsToKeep option.

    tagsToKeep: ['i', 'script[src]']

Default tags to keep are ['hr', 'img', 'embed', 'iframe', 'input'].

Auto grow

The text editing zone can extend itself when writing a long text. To activate this feature, use the autogrow option:

    autogrow: true

Autogrow is not active by default (set to false).

Auto grow on enter

Added in 2.7.0

The text editing zone can extend itself when editor get focus and reduce on blur. To activate this feature, use the following option:

    autogrowOnEnter: true

Autogrow on enter is not active by default (set to false).

Image width modal edit

Added in 2.9.0

Add a field in image insert/edit modal which allow users to set the image width. To activate this feature, use the following option:

    imageWidthModalEdit: true

Image width modal edit is not active by default (set to false).

URL protocol

Added in 2.9.4

An option to auto-prefix URLs with a protocol.

When this option is set to true, URLs missing a protocol will be prefixed with https://. Alternatively, a string can be provided for a custom prefix.

For example, a value of true would convert to, while a value of ftp converts to

    urlProtocol: true

Anchors, email addresses and relative links are left unchanged.

URL protocol is not active by default (set to false).

Added in 2.9.4

Reduce the link overlay to use only url and text fields, omitting title and target.

    minimalLinks: true

The minimal links option is not active by default (set to false).

Added in 2.26.0

Allow to set link target attribute value to what you want, even if the minimalLinks option is set to true.

First value is the default value (similar to previous defaultLinkTarget option).

    linkTargets: ['_blank', '_self']

Link targets only list most used options by default (set to ['_self', '_blank']).

Upgrade from defaultLinkTarget

-    defaultLinkTarget: '_blank',
+    linkTargets: ['_blank', '_self', '_parent', '_top'],

Tag classes

Added in 2.23.0

Add classes to any tag.

    tagClasses: {
        h1: 'h1', // Bootstrap example
        blockquote: 'bg-grey-100 rounded-xl', // Tailwind CSS example

No classes are applied by default.

Advanced Options

Add a localization

The structure of a language file is simple, it is a JavaScript Object which associate a translation to any key. For example: = {
    _dir: "ltr", // Changes the editor dir

    bold: "Gras",
    close: "Fermer"

Some localizations are added each day, you can find them in the langs folder on GitHub

You can submit a new localization file by creating a new pull request on the Github repository.

English is the default localization, you don't need to include any file to get Trumbowyg in English.

Custom buttons

If Trumbowyg does not fit your needs, maybe you can create your very own custom button to solve this. The following code (which does not works as is) show you all available button parameters.

    btnsDef: {
        buttonName: {
            fn: 'functionName',
            tag: 'tagName',
            title: 'Button tooltip',
            text: 'Displayed button name',
            isSupported: function () { return true; },
            key: 'K',
            param: '' ,
            forceCSS: false,
            class: '',
            hasIcon: true

The key (here buttonName) is the button name used in btns and in dropdown. It is used as many default in options below.


fn string|function
The name of a Trumbowyg internal method OR a callable function OR browser native execCommand name. In any case, the function is called when the user click on the button or use the associated shortcut.
Default: button name
tag string
The HTML tag name which highlight the button if cursor is in a tag which this tag name.
Default: button name
title string
The text displayed in a tooltip on mouse over a button.
Default: text parameter OR translated button name OR raw button name
text string
The text of the button used when svgPath is set to false. This text can be hidden via hideButtonTexts option.
Default: title parameter OR translated button name OR raw button name
isSupported function
A function which returns a Boolean to know if the custom button is supported (browser compatibility check, context check, ...)
Default: null (no check)
key string
Shortcut key which triggers the button function (fn)
Default: null (no shortcut defined)
param string
In case of using browser native execCommand, give this as parameter.
Default: button name
forceCSS string
In case of using browser native execCommand, force usage of inline CSS insteed of a tag.
Default: false
class string
A string which is added to the button class attribute.
Default: Trumbowyg adds a prefix + '-' + buttonName class
hasIcon boolean
Allow us to force the display of the text for a specific button.
Default: true

Working example:

    btnsDef: {
        alert: {
            fn: function() {
                alert('some text')
            ico: 'blockquote'
    btns: [

Custom dropdowns

You can also create your own dropdown, like buttons. The following code (which does not works as is) show use all options which can be used to make our own customized dropdown.

    btnsDef: {
        dropdownButtonName: {
            dropdown: ['btnA', 'btnB'],
            title: 'Displayed dropdown button name',
            ico: 'iconName',
            hasIcon: true


dropdown array<string>
A list of button names to list in the dropdown.
Default: []
title string
The text displayed in a tooltip on mouse over the dropdown button.
Default: translated dropdown button name OR raw dropdown button name
ico string
The icon name for the dropdown. You can reuse some existing icons from Trumbowyg.
Default: icon with button name in snake case
hasIcon boolean
Allow us to force the display of the text for a specific button.
Default: true

Working example which groups all justify buttons in one dropdown:

    btnsDef: {
        align: {
            dropdown: ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],
            ico: 'justifyLeft'
    btns: [


When you want create your custom extension for Trumbowyg, you can open and close a modal box with custom inner HTML code, listen events and more.

Open and close

For that use the .trumbowyg() method and give parameters 'openModal' or 'closeModal' like that:

// Open a modal box
var $modal = $('#editor').trumbowyg('openModal', {
    title: 'A title for modal box',
    content: '<p>Content in HTML which you want include in created modal box</p>'

// Close current modal box

An openModal call returns a jQuery object which contains the modal box. You need this object if you want to use listen events (see below).

Only one modal box can open at any given moment. So, openModal return false if a modal is currently opened.

Events on modal box

Modal boxes in Trumbowy come with two buttons: "Confirm" and "Cancel". An event is associated to each one:

  • tbwsubmit: triggered when form is submit
  • tbwreset: triggered when user cancel operation

// Open a modal box
var $modal = $('#editor').trumbowyg('openModal', {
    title: 'A title for modal box',
    content: '<p>Content in HTML which you want include in created modal box</p>'

// Listen clicks on modal box buttons
$modal.on('tbwconfirm', function(e){
    // Save data
$modal.on('tbwcancel', function(e){

Only build inputs in modal

If you want only add inputs in the modal box, this function is more simple. Indeed, you do not manage confirm and close buttons, and get all input value on confirm.

var img = $('img#an-img');
$("#editor").trumbowyg('openModalInsert', {
    title: 'A title for modal box',
    fields: {
        url: {
            value: img.attr('src')
        alt: {
            label: 'Alt',
            name: 'alt',
            value: img.attr('alt'),
            type: 'text',
            attributes: {}
        example: {
            // Missing label is replaced by the key of this object (here 'example')
            // Missing name is the key
            // When value is missing, value = ''
            // When type is missing, 'text' is assumed. You can use all the input field types,
            //   plus checkbox and radio (select and textarea are not supported)
            // When attributes is missing, {} is used. Attributes are added as attributes to
            //   the input element.
            // For radio and checkbox fields, you will need to use attributes if you want it
            //   to be checked by default.
    // Callback is called when user confirms
    callback: function(values){
        img.attr('src', values['url']);
        img.attr('alt', values['alt']);

        return true; // Return true if you have finished with this modal box
        // If you do not return anything, you must manage the closing of the modal box yourself

// You can also listen for modal confirm/cancel events to do some custom things
// Note: the openModalInsert callback is called on tbwconfirm
$modal.on('tbwconfirm', function(e){
    // Do what you want
$modal.on('tbwcancel', function(e){


Managing correctly text range, is not so trivial. Trumbowyg has a system to save and restore selection range which does not involves typical getter/setter.

Save and get current range

// Save current range

// Restore last saved range

Get selection range

// range contains a JavaScript range
var range = $('#editor').trumbowyg('getRange');

Get last saved range text

var text = $('#editor').trumbowyg('getRangeText');

Manage content

You can set and get current HTML content of the editor with a getter/setter:

// Get HTML content

// Set HTML content
$('#editor').trumbowyg('html', "<p>Your content here</p>");


You can empty the content of the editor.


Enable/disable edition

Added in 2.1.0

As you can disable editor by using disabled option, you can also switch between enabled and disabled states by using API.


Toggle between HTML & WYSIWYG modes

Added in 2.9.0

You can switch between HTML view and WYSIWYG view via toggle method.


Destroy editor

When you wish, you can restore the previous state of the element was used to create the editor.



Some events are fired on the jQuery element which is used to build the editor.

  • Focus on editor: tbwfocus
  • Blur on editor: tbwblur
  • Editor is initialized: tbwinit 2.0.0
  • Change in editor: tbwchange 2.0.0
  • Resize the editor on autogrow: tbwresize 2.0.0
  • Paste something in the editor: tbwpaste 2.0.0
  • Switch to fullscreen mode: tbwopenfullscreen 2.0.0
  • Leave editor's fullscreen mode: tbwclosefullscreen 2.0.0
  • Close the editor: tbwclose 2.0.0
  • Modal open: tbwmodalopen 2.20.0
  • Modal close: tbwmodalclose 2.20.0

.trumbowyg() // Build Trumbowyg on the #editor element
.on('tbwfocus', function(){ console.log('Focus!'); }); // Listen for `tbwfocus` event
.on('tbwblur', function(){ console.log('Blur!'); }); // Listen for `tbwblur` event