Important changes to Tiny Cloud pricing > Find out more

Create a plugin for TinyMCE

A short introduction to creating plugins for TinyMCE along with an example plugin.

Contribute to this page

TinyMCE is designed to make creating plugins simple and to provide choice. Users can employ the Yeoman generator or you can use the following tutorial that outlines the basic concepts of creating a plugin. Consult the API documentation and review the existing plugins that are shipped with the core editor for additional details.

File Structure

First create a directory in the TinyMCE plugins directory. TinyMCE loads the plugin.js file when developers use the tinymce.js file in the page. Similarly, the tinymce.min.js loads the plugin.min.js file. The recommended usage is to use the tinymce.js file while developing and then use a build script minifying the plugin.js into plugin.min.js in production.

The build scripts that comes with the TinyMCE development package automatically builds all plugins including custom ones.

Example of the plugin file structure


This new example plugin can be loaded using the tinymce.init plugins option.

  selector: 'textarea',
  plugins: 'example'

Developers can designate the location of the plugins by loading the plugin.js or plugin.min.js files directly after the tinymce.js or tinymce.min.js.

Example of loading the plugin from another URL

<script src="/tinymce/js/tinymce.min.js"></script>
<script src="/scripts/my.tinymce.plugin.js"></script>

Example plugin

This example plugin demonstrates how to add a simple toolbar button and menu item. This button opens a dialog that allows a title to be entered into the editor. The menu item will open the same dialog as the button.

tinymce.PluginManager.add('example', function(editor, url) {
  var openDialog = function () {
      title: 'Example plugin',
      body: {
        type: 'panel',
        items: [
            type: 'input',
            name: 'title',
            label: 'Title'
      buttons: [
          type: 'cancel',
          text: 'Close'
          type: 'submit',
          text: 'Save',
          primary: true
      onSubmit: function (api) {
        var data = api.getData();
        // Insert content when the window form is submitted
        editor.insertContent('Title: ' + data.title);

  // Add a button that opens a window
  editor.ui.registry.addButton('example', {
    text: 'My button',
    onAction: function () {
      // Open window

  // Adds a menu item, which can then be included in any menu via the menu/menubar configuration
  editor.ui.registry.addMenuItem('example', {
    text: 'Example plugin',
    onAction: function() {
      // Open window

  return {
    getMetadata: function () {
      return  {
        name: 'Example plugin',
        url: ''

Example init

The following is an example of how to use the new toolbar button.

  selector: 'textarea',
  plugins: 'example',
  toolbar: 'example'

Exposing metadata

Metadata can be exposed from a custom plugin by returning an object with the property getMetadata with a function that returns an object with a name and url property. This metadata is used by the Help Plugin to show the correct name and link for the plugin in the Plugins installed tab. See the test plugin above for example.

Language localization

Create a “langs” directory in the plugin directory for custom translations. TinyMCE loads language files based on the specified language code. For example, if the language is “es_ES” it will try to load '<your plugin>/langs/es_ES.js'.

The structure is similar to .po files in that the English string left and its corresponding translation on the right.

Example of a Spanish translation for the dialog title

tinymce.addI18n('es_ES', {
  'Example plugin': 'Example plugin'

Warning: A 404 error will load if translations are missing in the plugin that the full TinyMCE package contains. Add the following line to the top of the plugin file to avoid this.

tinymce.PluginManager.requireLangPack('example', 'es_ES,de_AT');

Can't find what you're looking for? Let us know.

Except as otherwise noted, the content of this page is licensed under the Creative Commons BY-NC-SA 3.0 License, and code samples are licensed under the Apache 2.0 License.