Blueprint by Tiny
Return to
Return to Tiny.cloudTry TinyMCE for Free
Search by

How to create a CRM app with TinyMCE Self-hosted + Cloud

Joe Robinson

July 27th, 2022

Written by

Joe Robinson


How-to Use TinyMCE

Customer relationships – they’re at the heart of every business.

One method to keep and build customer relationships is a constant flow of personalized communication with each client. But what if, in the creation of those personal touches, you need your own equally personalized control over the tools you’re using? There are certain tools that can accomodate that exact need.

One such tool is a key component within every Customer Relationship Manager (CRM) software: a versatile WYSIWYG text editor. But you need one that works with both Self-hosted and Cloud setups.

The best CRM editor component that can support you, is TinyMCE. It’s the world’s most trusted WYSIWYG component that enables rich text editing capabilities within an application.

What this article covers is how to run a CRM with TinyMCE Self-hosted and TinyMCE Cloud working together, as a WYSIWYG component for your communication. It explains the steps of setting up TinyMCE Self-hosted, and then how to include TinyMCE Cloud for Premium Plugins. Finally, you can discover how to add TinyMCE as a versatile component inside an example CRM config.

How to set up TinyMCE Self-hosted

The very first step – download a copy of TinyMCE in .zip format.

  1. On the Get-tiny sign up page, click the Download TinyMCE SDK Now button. A .zip file then starts downloading into your downloads folder.

This .zip file holds the rich text editor. This is what you host on your own workstation.

  1. Unzip the TinyMCE file you downloaded in the previous step (the file name - or similar).

  2. Create a new folder on your workstation, and move the unzipped TinyMCE file into the folder.

  3. Create a new index.html file in the directory. Include the initial HTML content to get a web page going:

<!doctype html>

<meta charset="utf-8">
<title>TinyMCE as a CRM component</title>


  1. Inside the head HTML tags of the document, reference the local tinymce.min.js file, that is, the address of the tinymce.min.js file stored in the folder next to your index.html file:

<script src="/tinymce/js/tinymce/tinymce.min.js"></script>
  1. To get TinyMCE started in the file, place another script tag after the Self-hosted content, and include the tinymce.init content:


            selector: "#editor"
  1. Add a pair of textarea tags into your html file body. Give them the id of “editor”:

    <textarea id="editor">

With these steps complete, you’ve successfully set up an essential TinyMCE Self-hosted (excellent work!). Now to combine it with TinyMCE Cloud.

TinyMCE Cloud and TinyMCE Self-hosted together

The TinyMCE Cloud component

First of all, to get TinyMCE set up as a hybrid configuration, you’ll need a TinyMCE API key.

Getting your TinyMCE API key

This key gives you free access to TinyMCE Premium plugins for 14 days. Why seek out the API key? 

  • The Premium plugin preview gives you time to try out features for your CRM
  • Adding your API key to your CRM removes warning messages (see below) in the text area
  • Check on the CRM Solutions page to see the wealth of premium features

Yes, you can use TinyMCE without an API key – however, that triggers warning messages concerning domain registration that appear in the text area that will only disappear if you add an API key.

You can get your TinyMCE API key two ways:

  1. Navigate to the pricing plans for TinyMCE. Choose the plan that fits your app.

  2. Go directly to the Get-tiny sign up page to get your FREE API key.

Enter an email and password, and click Sign up. When you arrive at the TinyMCE dashboard, your API key appears in the middle of the page.

How to add the TinyMCE Cloud component

  1. Add a link to TinyMCE with your API key in your index.html head before the TinyMCE Self-host link:

<script src="" referrerpolicy="origin"></script>
  1. With the TinyMCE Cloud link added, you can now try out Premium plugins.

    Replace the inital tinymce.script content from the previous steps with the following:
                selector: "#editor",
                menubar: false,
                statusbar: false,
                plugins: 'lists link emoticons image editimage advcode linkchecker template powerpaste tinymcespellchecker autoresize',
                toolbar: 'undo redo spellchecker | formatgroup | link emoticons image template tokens | code',
                toolbar_groups: {
                    formatgroup: {
                        icon: 'format',
                        tooltip: 'Formatting',
                        items: 'blocks fontfamily fontsize | bold italic underline strikethrough forecolor | align bullist numlist outdent indent blockquote'
                toolbar_location: 'bottom',
                min_height: 300,
                max_height: 500,
                autoresize_bottom_margin: 20,
  1. Save these changes

Next steps

What you’ve just completed is the initial CRM editor configuration, and you can now integrate it into your CRM as a component for text entry.

The next section builds on this essential configuration.

Configuring a CRM editor around TinyMCE

This CRM editor config draws some sample content from the TinyMCE CRM config.

The first change to make is showing how TinyMCE fits into a CRM. So, here’s how to shape the CRM config, and further add to TinyMCE functionality with more premium plugins:

  1. Add the templates plugin values into the tinymce.init script after the autoresize plugin configuration: 
 templates: [
                        title: 'Outbound email',
                        description: 'Outbound cold email for prospects',
                        content: '<p style="font-size: 14px; font-family: helvetica, arial, sans-serif;">Hi  {{ lead.firstname }},</p><p style="font-size: 14px; font-family: helvetica, arial, sans-serif;">My name is  {{ user.lastname }}with  {{ user.organization }}.</p><p style="font-size: 14px; font-family: helvetica, arial, sans-serif;">We help companies just like yours securely store data in the cloud. I wanted to learn how you handle data storage at  {{ lead.organization }}and show you some of the exciting technology we\'re working on.</p><p style="font-size: 14px; font-family: helvetica, arial, sans-serif;">Are you available for a quick call tomorrow afternoon?</p><p style="font-size: 14px; font-family: helvetica, arial, sans-serif;"> {{ user.firstname }}</p>'
                    }, {
                        title: 'Follow-up email',
                        description: 'Follow-up to be sent immediately after discovery meetings',
                        content: '<p style="font-size: 14px; font-family: helvetica, arial, sans-serif;">Hi  {{ lead.firstname }},</p><p style="font-size: 14px; font-family: helvetica, arial, sans-serif;">Thank you for taking the time to explore a potential partnership today! It felt like our product could help you solve some of the issues that you’re having within  {{ lead.organization }}, especially in these areas:</p><ul><li style="font-size: 14px; font-family: helvetica, arial, sans-serif;">The offsite data warehouse will allow you to guarantee business continuity</li><li style="font-size: 14px; font-family: helvetica, arial, sans-serif;">Metered usage will ensure you only pay for what you consume</li><li style="font-size: 14px; font-family: helvetica, arial, sans-serif;">Level III security protocols will mean you will meet security requirements for your jurisdiction</li></ul><p style="font-size: 14px; font-family: helvetica, arial, sans-serif;">I understand that now you will discuss and agree internally on the next step. Please let me know if you have any questions or if there is anything I can do to help. If not, I’ll talk to you next week.</p><p style="font-size: 14px; font-family: helvetica, arial, sans-serif;">Best,<br> {{ user.firstname }}</p>'
                noneditable_regexp: /\{\{[^\}]+\}\}/g,

                setup: (editor) => {
                    editor.ui.registry.addIcon('token', '<svg enable-background="new 0 0 24 24" height="24" viewBox="0 0 24 24" width="24" xmlns="<a href=""></a>"><path d="m0 0h24v24h-24z" fill="none"/><path d="m21 12-4.37 6.16c-.37.52-.98.84-1.63.84h-3v-2h3l3.55-5-3.55-5h-10v3h-2v-3c0-1.1.9-2 2-2h10c.65 0 1.26.31 1.63.84zm-11 3h-3v-3h-2v3h-3v2h3v3h2v-3h3z"/></svg>');
                    editor.ui.registry.addMenuButton("tokens", {
                        icon: "token",
                        tooltip: "Insert token",
                        fetch: (callback) => {
                            var items = => {
                                return {
                                    type: "menuitem",
                                    text: token.text,
                                    onAction: () => {
                                        // Insert content at the location of the cursor.
  1. Add style content for the rich text editor after the templates plugin configuration:
 content_style: `
                   body {
                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, Arial, sans-serif;
                    font-size: 14px;
                    line-height: 1.5rem;

                   h1 {
                    font-size: 24px;

                   h2 {
                    font-size: 18px;

                   .mceNonEditable {
                     background-color: #e7ecff;
                     padding: 1px 0;
                     color: #4059b3;
                     font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
                     font-size: 0.9375em;
  1. Next add style tags inside the head section of the HTML file, and include some CSS:
            body {
                font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif;
                font-size: 14px;
                margin: 2rem;

            main {
                max-width: 800px;
                margin: auto;

            .box {
                cursor: not-allowed;
                color: rgb(198, 204, 220);
                max-width: 42rem;
                margin: 0 auto;
                display: flex;
                align-content: flex-start;
                gap: 2rem;
                align-items: flex-start;
                line-height: 1.125rem;
                font-style: normal;
                font-weight: 500;
                font-size: 0.875rem;

            .heading {
                align-content: flex-start;
                margin: 0 auto;
                padding: 0.75rem 0;
                background: rgb(255, 255, 255);
                display: flex;
                gap: 2rem;
                align-items: flex-start;
                line-height: 1.125rem;
                font-style: normal;
                font-weight: 500;
                font-size: 0.875rem;

            .button {
                display: flex;
                align-content: flex-start;
                cursor: not-allowed;
                padding: 0.25rem 0.5rem;
                font-size: 0.875rem;
                color: rgb(198, 204, 220);
                border: 1px solid rgb(223, 227, 236);
                border-radius: 0.25rem;
                background: rgb(255, 255, 255);
  1. Place some more CRM HTML content inside the body section before the TinyMCE textarea:
            <div class="heading">
                <div class="box">New Task</div>
                <div class="box">Log a Call</div>
                <div class="box">New Event</div>
                <div class="box">Email</div>

        <div class="button">
            <label class="box">From
                <span>Sarah Humberson <></span>
            <label class="box">To
                <span>Art Vandelay <></span>
            <label class="box">Subject
                <span>Following up on our call</span>
  1. Modify the TinyMCE textarea HTML, expanding it from the minimal html tags introduced in previous steps:
<textarea id="editor">
            <h2>What's your CRM editor project?</h2>
            <p>Are you:</p>
                <li>Building a new CRM and need to add rich text editing capabilities?</li>
                <li>Extending your existing CRM and need a more extensive rich text editor?</li>
            <p>Then use the only WYSIWYG CRM editor that’s trusted by 1.5M devs.</p>
                <strong>Curious about TinyMCE?</strong>
                Play with this demo to see how our CRM editor works 😊</p>
                <img src="" width="18" height="18" alt="Formatting"> to see how a toolbar group works, and click on
                <img src="" width="18" height="18" alt="Insert Template">
                <img src="" width="18" height="18" alt="Insert Token">
                for inspiration to include pre-defined templates and merge tags.</p>
  1. Finally, add the last HTML content between the textarea closing tag and the closing body tag:
<div class="heading">
            <div class="box">
                <label>Related to</label>
                <span class="button">Vandelay Industries</span>
                <div class="button">Send</div>
                <div class="button">Schedule</div>
                <div class="button">Save draft</div>
  1. Save the changes, and load the HTML file in your browser:

TinyMCE in a CRM demo config with the plugins working

With a combined TinyMCE Cloud and Self-hosted setup, you can work knowing that the core editor is supported on your local workstation, and that you have access to an array of premium features through the TinyMCE Cloud CDN connection.

A note on non-editable content

Any content wrapped in the “{{ }}” curly bracers appears non-editable. This prevents change to vital customer information.

The appearance of the non-editable areas are styled with a class – the CSS style applied to the class in the tinymce.init script controls and changes their appearance.

The next steps for your CRM editor

Check out our CRM editor page next – the procedure in this article covers just one facet of the TinyMCE configuration that works best for a CRM – there are a wealth of opportunities and plugins that you can adapt to fit your CRM project plans.

Remember that your FREE API key grants free access to Premium Plugin functionality for 14 days, after which you need to either choose a Premium Plan or remove the TinyMCE premium features.

TinyMCESelf HostingConfigurationCRM
byJoe Robinson

Technical and creative writer, editor, and a TinyMCE advocate. An enthusiast for teamwork, open source software projects, and baking. Can often be found puzzling over obscure history, cryptic words, and lucid writing.

Related Articles

  • How-to Use TinyMCE

    How to create a word processor to rival MSWord and Google Docs – tutorial

    by Di Mace, Joe Robinson, & John Rau in How-to Use TinyMCE
Subscribe for the latest insights served straight to your inbox every month.

Deploy TinyMCE in just 6 lines of code

Built to scale. Developed in open source. Designed to innovate.

Begin with your FREE API Key
Tiny Editor
Tiny logo
Privacy Policy - Terms of Use© 2022 Tiny Technologies Inc.TinyMCE® and Tiny® are registered trademarks of Tiny Technologies, Inc.


  • TinyMCE
  • Tiny Drive
  • Customer Stories
  • Pricing