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

Creating plugins in TinyMCE is pretty simple - especially if you use the Yeoman generator! - but if you would rather do it all by yourself, keep reading.

This tutorial tries to outline some of the basic concepts of creating a plugin. For more details consult the API documentation and check the existing plugins we ship with the core.

File Structure

To create a plugin, you need to create a directory in the TinyMCE plugins directory. TinyMCE will load the plugin.js file if you use the tinymce.js file in your page. If you use the tinymce.min.js file, it will load the plugin.min.js file. It's recommended to use the tinymce.js file while developing then have a build script minifying the plugin.js into plugin.min.js for production usage.

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

Example of the plugin file structure


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

  selector: 'textarea',
  plugins: 'example'

You can also have the plugin in any location you want by loading the plugin.js/plugin.min.js files directly after the tinymce.js/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

Here is an example plugin showing how you add a simple toolbar button and menu item. The button opens a dialog that lets you type in a title that gets inserted into the editor. The menu item will open the TinyMCE site in a dialog.

tinymce.PluginManager.add('example', function(editor, url) {
  // Add a button that opens a window
  editor.addButton('example', {
    text: 'My button',
    icon: false,
    onclick: function() {
      // Open window{
        title: 'Example plugin',
        body: [
          {type: 'textbox', name: 'title', label: 'Title'}
        onsubmit: function(e) {
          // Insert content when the window form is submitted
          editor.insertContent('Title: ' +;

  // Adds a menu item to the tools menu
  editor.addMenuItem('example', {
    text: 'Example plugin',
    context: 'tools',
    onclick: function() {
      // Open window with a specific url{
        title: 'TinyMCE site',
        url: '',
        width: 800,
        height: 600,
        buttons: [{
          text: 'Close',
          onclick: 'close'

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

Example init

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

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

Exposing metadata

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

Language localization

If you want to have custom translations for your plugin you need to create a "langs" directory in your plugin directory. TinyMCE will then try to load language files based on the specified language core for example if the language is "sv_SE" it will try to load '<your plugin>/langs/sv_SE.js'.

This file is similar to .po files it has the English string on the left side and the translated string on the right side.

Example of a Swedish translation for the dialog title

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

Sometimes you don't have all the translations that the full TinyMCE package has this would result in a 404 error while loading the non-existing file. This can be avoided by adding this line to the top of your plugin file.

tinymce.PluginManager.requireLangPack('example', 'sv_SE,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.