How to Add Valid Elements (like iframes) to TinyMCE in EPiServer 7

March 2022 Update: This post was originally written for EPiServer version 7. In 2021, Episerver (now known as Optimizely) released version 12. While some parts of this post are outdated, other parts are still relevant and may be helpful. If you run into any issues when configuring TinyMCE, you should refer to Optimizely's official documentation. No content in this post has been changed for the current version.

In a recent EPiServer 7 project, our client needed support for iframes and some other HTML tags in the TinyMCE WYSIWYG editor. Luckily, the way you add valid elements to TinyMCE hasn't changed much between EPiServer 6 and EPiServer 7, though some small issues have made the update a little more involved. In this post, I'll show you how to add valid elements to TinyMCE and how to fix the issues you'll potentially encounter along the way.

What Hasn't Changed

Like EPiServer 6, you need to add a simple class to your project to register the extended valid elements. The name and location of the class does not matter, as long as it is compiled into your project. The most important part of this that we are focusing on is the TinyMCEPluginNonVisual attribute

[TinyMCEPluginNonVisual(AlwaysEnabled = true, EditorInitConfigurationOptions = "{ extended_valid_elements: 'iframe[src|frameborder=0|alt|title|width|height|align|name]' }")]
public class TinyMceExtendedValidElements
{
}

As you can see in above code, our example is pretty simple. We are just telling TinyMCE to allow the iframe tag and some attributes.

Next, you need to update episerver.config...

<episerver>
    ... some configuration ...
    <tinyMCE mergedConfigurationProperties="valid_elements, extended_valid_elements, invalid_elements, valid_child_elements" />
</episerver>

Where Issues Arise

After you add the class to your project and update the configuration file, you may notice that the TinyMCE editor doesn't load. If you open up Fiddler or your browser's developer tool utility, you can see a 404 error is thrown for a particular JavaScript file.

TinyMCE Error

TinyMCE Error

The browser is looking for a file in the path /util/Editor/tinymce/plugins//editor_plugin.js. The // hints that something is missing, and that something is the plug-in name. So from here, we can update our class to include the PlugInName...

[TinyMCEPluginNonVisual(PlugInName = "TinyMceExtendedValidElements", AlwaysEnabled = true, EditorInitConfigurationOptions = "{ extended_valid_elements: 'iframe[src|frameborder=0|alt|title|width|height|align|name]' }")]
public class TinyMceExtendedValidElements
{
}

And when we build the project and refresh the browser, we can see the exact path that TinyMCE needs:

TinyMCE Error

But now the issue is that we don't have a file at that location, and in fact, we don't need one. Ted Nyberg used to a good workaround to solve this... Simply use an empty file handler to serve up a blank file. Here is the code for our empty file handler:

public class EmptyFileHandler : IHttpHandler
{
    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
    }
}

Then to hook this up, just add this configuration to web.config that only targets the path that TinyMCE is looking for:

<configuration>
    ... some configuration ...
    <location path="util/editor/tinymce/plugins">
        <system.webServer>
            <handlers>
                <add name="TinyMceExtendedValidElements" path="/util/editor/tinymce/plugins/TinyMceExtendedValidElements/editor_plugin.js" verb="GET" type="MyEPiServerProject.Business.Handlers.EmptyFileHandler, MyEPiServerProject" />
            </handlers>
        </system.webServer>
    </location>
</configuration>

And there we have it! Now TinyMCE will stop removing iframe tags from the saved content.

From here, you can simply update the parameter in the TinyMCEPluginNonVisual attribute on the class to allow any other tags and attributes that you need to support in your content.

Resources: