Start trial
PricingContact Us
Log InStart For Free

How to migrate from Tiptap to TinyMCE

March 7th, 2022

4 min read

Migrate from Tiptap to TinyMCE following these steps

Written by

Ben Long

Category

How-to Use TinyMCE

Simplify the amount of time and coding your development team spends on developing the rich text components in your products by using TinyMCE. TinyMCE is the world’s most popular rich text editor, powering 100+ million products worldwide. The editor is easy to deploy and is highly customizable to suit a broad range of applications and edge cases.

Tiptap provides a headless, collaborative, framework-agnostic rich text editor for developers to integrate into their applications. However, highly customizable solutions often mean code heavy solutions; for example, you can see in the example below that developers often have to use five lines of code in Tiptap where only one word does the same job in TinyMCE.

TinyMCE also provides a collaborative, framework-agnostic editor, and although it’s not strictly considered a “headless” editor, it comes ready to use with the UI easily customized to suit any application as demonstrated by these 9 examples of products built with TinyMCE.

With React maintaining its position as the most popular web framework, according to the 2021 Developer Survey, in this article we will demonstrate migration from Tiptap to TinyMCE within the React framework. Migrations among other frameworks will be similar.

TipTap rich text editor working

Tiptap basic configuration.

TinyMCE rich text editor working with WYSIWYG up

TinyMCE basic configuration.

1. Installation

There are many ways in which you may have structured your code; however, we will base this migration on the Tiptap installation documentation that makes use of a Tiptap.jsx file for the editor component which is then used within an App.js file. A basic configuration is shown below.

// src/Tiptap.jsx
import { useEditor, EditorContent } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";

const Tiptap = () => {
  const editor = useEditor({
    extensions: [StarterKit],
    content: "<p>Hello, World!</p>",
  });

  return <EditorContent editor={editor} />;
};

export default Tiptap;
// src/App.js
import Tiptap from "./Tiptap.jsx";

const App = () => {
  return (
    <div className="App">
      <Tiptap />
    </div>
  );
};

export default App;

When using TinyMCE, there is no need to code a specific component for the editor – the editor is already available as a component to use within your application.

First, install the tinymce-react component from the command line with your package manager of choice; for example, if using npm:

npm install @tinymce/tinymce-react

Open the App.js file and modify it to import the TinyMCE component and change the reference to the Tiptap component with a reference to the TinyMCE Editor component instead, as shown in the code snippet below. Also replace no-api-key with your own Tiny API key. If you don’t already have one, you can get a free API key now which will provide you with access to all the standard text formatting options plus 44 core plugins that you can add or remove as needed to further enhance the editing experience.

// src/App.js
import React from "react";
import { Editor } from "@tinymce/tinymce-react";

const App = () => {
  return (
    <div className="App">
      <Editor apiKey="no-api-key" initialValue="<p>Hello, World!</p>" />
    </div>
  );
};

export default App;

2. Configuration

Most likely you will have configured your Tiptap editor with an assortment of user options in the form of a toolbar. In Tiptap, you will have configured each of these with multiple lines of code. For example, check out the following Tiptap configuration that provides 15 commonly used toolbar options to users.

// src/Tiptap.jsx
import { useEditor, EditorContent } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";

const MenuBar = ({ editor }) => {
  if (!editor) {
    return null;
  }

  return (
    <>
      <button
        onClick={() => editor.chain().focus().toggleBold().run()}
        className={editor.isActive("bold") ? "is-active" : ""}
      >
        bold
      </button>
      <button
        onClick={() => editor.chain().focus().toggleItalic().run()}
        className={editor.isActive("italic") ? "is-active" : ""}
      >
        italic
      </button>
      <button
        onClick={() => editor.chain().focus().toggleStrike().run()}
        className={editor.isActive("strike") ? "is-active" : ""}
      >
        strike
      </button>
      <button
        onClick={() => editor.chain().focus().toggleCode().run()}
        className={editor.isActive("code") ? "is-active" : ""}
      >
        code
      </button>
      <button onClick={() => editor.chain().focus().unsetAllMarks().run()}>
        clear marks
      </button>
      <button
        onClick={() => editor.chain().focus().setParagraph().run()}
        className={editor.isActive("paragraph") ? "is-active" : ""}
      >
        paragraph
      </button>
      <button
        onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}
        className={editor.isActive("heading", { level: 1 }) ? "is-active" : ""}
      >
        h1
      </button>
      <button
        onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
        className={editor.isActive("heading", { level: 2 }) ? "is-active" : ""}
      >
        h2
      </button>
      <button
        onClick={() => editor.chain().focus().toggleBulletList().run()}
        className={editor.isActive("bulletList") ? "is-active" : ""}
      >
        bullet list
      </button>
      <button
        onClick={() => editor.chain().focus().toggleOrderedList().run()}
        className={editor.isActive("orderedList") ? "is-active" : ""}
      >
        ordered list
      </button>
      <button
        onClick={() => editor.chain().focus().toggleCodeBlock().run()}
        className={editor.isActive("codeBlock") ? "is-active" : ""}
      >
        code block
      </button>
      <button
        onClick={() => editor.chain().focus().toggleBlockquote().run()}
        className={editor.isActive("blockquote") ? "is-active" : ""}
      >
        blockquote
      </button>
      <button onClick={() => editor.chain().focus().setHorizontalRule().run()}>
        horizontal rule
      </button>
      <button onClick={() => editor.chain().focus().undo().run()}>undo</button>
      <button onClick={() => editor.chain().focus().redo().run()}>redo</button>
    </>
  );
};
const Tiptap = () => {
  const editor = useEditor({
    extensions: [StarterKit],
    content: "<p>Hello, World!</p>",
  });

  return (
    <div>
      <MenuBar editor={editor} />
      <EditorContent editor={editor} />
    </div>
  );
};

export default Tiptap;

On the other hand, when using TinyMCE, configuring toolbar options is as easy as including a single word for each option on initialization. For instance, the following code in the App.js file will provide the same user options as those provided by the Tiptap code above.

const App = () => {
  return (
    <div className="App">
      <Editor
        apiKey="no-api-key"
        initialValue="<p>Hello, World!</p>"
        init={{
          menubar: false,
          plugins: "lists code hr",
          toolbar:
            "bold italic strikethrough code removeformat h1 h2 bullist numlist code blockquote hr undo redo",
          width: 700,
        }}
      />
    </div>
  );
};

More information about the init method and the plugin and toolbar options can be found in the Tiny docs.

Complete example

Here is a complete example of the TinyMCE configuration that you can use as a starting point for your migration from Tiptap. To get started, create a new react app, install the tinymce-react component from the command line as shown above, and replace the code in App.js with the following:

import React from "react";
import { Editor } from "@tinymce/tinymce-react";

const App = () => {
  return (
    <div className="App">
      <Editor
        apiKey="no-api-key"
        initialValue="<p>Hello, World!</p>"
        init={{
          menubar: false,
          plugins: "lists code hr",
          toolbar:
            "bold italic strikethrough code removeformat h1 h2 bullist numlist code blockquote hr undo redo",
          width: 700,
        }}
      />
    </div>
  );
};

export default App;

Completed migration from tiptap to TinyMCE

The headless editor

One of the touted benefits to using Tiptap is that it is “headless”, meaning that there is no provided user interface and that you are “free to build whatever interface you want.”

Although TinyMCE comes with a default interface out of the box to help you get your applications up and running quickly, it is easy to customize to suit whatever UX you are aiming for. This helps you provide innovative solutions that will delight your users.

  • Custom skins - Customizing TinyMCE is simplified with the premium skins and icons pack. There is also the TinyMCE 5 Skin Tool that can help you create your own custom skins. 

  • Custom toolbar configuration and options - Once you have migrated to TinyMCE, you have loads of new configuration options and UI customizations available to enhance your application’s user experience. Check out our article about how to customize toolbar options.

email marketing tool completed

An email marketing tool built with TinyMCE.

What’s next?

More help with TinyMCE in React - There’s loads more information about integrating TinyMCE with your React applications on our blog.

Additional help and support - For more complex migrations, you can contact our support team at any time for assistance. We are ready to help you take your applications to the next level.

 

HTMLMigrationTinyMCEWYSIWYG
byBen Long

Computer scientist, storyteller, teacher, and an advocate of TinyMCE. Reminisces about programming on the MicroBee. Writes picture books for kids. Also the wearer of rad shoes. “Science isn’t finished until you share the story.”

Related Articles

  • How-to Use TinyMCENov 21st, 2024

    What are Line Breaks? Learn How to Add and Remove Them

Join 100,000+ developers who get regular tips & updates from the Tiny team.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Tiny logo

Stay Connected

SOC2 compliance badge

Products

TinyMCEDriveMoxieManager
© Copyright 2024 Tiny Technologies Inc.

TinyMCE® and Tiny® are registered trademarks of Tiny Technologies, Inc.