Skip to main content

Outline

At a glance
  • Core lever: Configure TinyMCE via DI using IConfigureOptions<TinyMceConfiguration> (Options pattern).
  • Scope hierarchy: Global Default() → content type → property override (most specific wins).
  • Governance: Toolbar + plugins shape stored HTML; valid_elements governs what can exist.
  • PaaS reality: Configuration is code-driven and promoted via CI/CD (treat changes like schema evolution).

Introduction

In Optimizely CMS 12 (PaaS), TinyMCE is not merely a visual editing tool — it is a configurable content input system that directly shapes the HTML stored in the CMS database. For developers building structured, scalable, and maintainable solutions, configuring rich text settings is not optional. It is a core architectural decision.

The TinyMCE Configuration API in CMS 12 enables developers to:

  • Control which plugins are available
  • Define toolbar layouts
  • Restrict allowed HTML elements
  • Apply configuration per content type or per property
  • Extend the editor with custom behaviors

This article explores the full configuration surface of TinyMCE in CMS 12 using the official Configuration API, property-level configuration, plugin model, and default settings.

The focus is strictly on CMS 12 deployed in PaaS/DXP environments.

1. The TinyMCE configuration architecture

TinyMCE configuration in CMS 12 is implemented using the ASP.NET Core options pattern. The primary extension point is:

IConfigureOptions<TinyMceConfiguration>

Configuration is registered during application startup and injected via dependency injection.

Example:

using EPiServer.Cms.TinyMce.Core; using Microsoft.Extensions.Options; public class ConfigureTinyMceOptions : IConfigureOptions<TinyMceConfiguration> { public void Configure(TinyMceConfiguration config) { config.Default() .AddPlugin("lists") .Toolbar("bold italic | bullist numlist"); } }

Registration in Program.cs:

builder.Services.ConfigureOptions<ConfigureTinyMceOptions>();

This pattern ensures:

  • Configuration is version-controlled
  • Behavior is consistent across environments
  • No runtime UI changes affect production unexpectedly

In PaaS deployments, this is critical because configuration changes require CI/CD promotion.

2. Global vs scoped configuration

The Configuration API supports layered scoping. Developers can configure:

  • Global defaults
  • Per content type
  • Per property

2.1 Global configuration

config.Default() .Toolbar("bold italic underline") .AddPlugin("link");

This applies to all XhtmlString properties unless overridden.

2.2 Content-type specific configuration

config.For<StandardPage>() .Toolbar("bold italic | link");

This applies to all XhtmlString properties inside StandardPage.

2.3 Property-level configuration

config.For<StandardPage>(p => p.MainBody) .Toolbar("bold italic underline | link image");

This hierarchy resolves in the following order:

  • Global default
  • Content-type configuration
  • Property-specific configuration

The most specific rule wins. This layered model allows precise editorial control without duplicating configuration.

3. Toolbar configuration

Toolbar configuration defines what editing actions are visible to editors.

Example:

config.Default() .Toolbar("formatselect | bold italic | bullist numlist | link image");

Toolbar syntax is string-based and follows TinyMCE conventions.

Important considerations:

  • Toolbar buttons must correspond to enabled plugins.
  • Removing toolbar buttons does not necessarily remove HTML capability unless elements are restricted.
  • Toolbar design influences editorial consistency.

A minimal toolbar strategy is often preferable in structured CMS implementations.

4. Plugin management

TinyMCE functionality is modular and driven by plugins.

Enable plugins using:

config.Default() .AddPlugin("code") .AddPlugin("table") .AddPlugin("lists");

Common built-in plugins include:

  • lists
  • link
  • image
  • table
  • code
  • paste

When enabling plugins:

  • Ensure toolbar reflects plugin features.
  • Avoid exposing unnecessary plugins.
  • Align with frontend rendering capabilities.

Overexposure of plugins can lead to inconsistent markup, especially in component-based frontend architectures.

5. Default settings and valid elements

CMS 12 ships with default TinyMCE settings. These govern:

  • Allowed elements
  • Valid attributes
  • Paste behavior
  • Formatting rules

Developers can override element validation using AddSetting.

Example:

config.Default() .AddSetting("valid_elements", "p,strong/b,em/i,ul,ol,li,a[href|target]");

This explicitly restricts allowed HTML.

Key implications:

  • Editors cannot insert unsupported tags.
  • Stored markup becomes predictable.
  • Frontend rendering remains controlled.

Without explicit restrictions, editors may insert markup that conflicts with design systems.

6. Style formats and structured patterns

Developers can define predefined style formats.

Example:

config.Default() .AddSetting("style_formats", new[] { new { title = "Callout", block = "div", classes = "callout-box" } });

This allows editors to apply structured CSS classes without manual HTML editing.

Best practice:

  • Define style formats that map directly to frontend components.
  • Avoid generic "free-form" styling.
  • Pair style formats with controlled CSS.

This bridges editorial freedom with design system enforcement.

7. Property-level configuration using attributes

In addition to global configuration, developers can configure properties using attributes.

Example:

[TinyMceSettings( Toolbar = "bold italic underline", Plugins = "lists link")] public virtual XhtmlString Summary { get; set; }

This approach:

  • Is localized to a specific property
  • Avoids modifying global configuration
  • Enables highly targeted control

However, excessive attribute-level configuration may reduce maintainability. In large solutions, centralized configuration is typically preferred.

8. Paste behavior and content cleanup

TinyMCE includes paste handling capabilities.

Developers can configure paste behavior to:

  • Strip unwanted formatting
  • Remove inline styles
  • Normalize content from Word or external sources

Example:

config.Default() .AddSetting("paste_as_text", true);

Strict paste handling improves content hygiene and reduces unexpected HTML.

9. Security considerations

Rich text configuration impacts application security.

Key areas:

  • Preventing script injection
  • Restricting dangerous attributes
  • Ensuring consistent HTML structure

Although TinyMCE limits certain behaviors by default, developers must ensure:

  • Valid elements are restricted appropriately
  • Custom plugins do not introduce vulnerabilities
  • Rendering logic does not bypass CMS sanitization

In PaaS deployments, security hardening must be part of code review and CI/CD validation.

10. Operational considerations in PaaS

Because CMS 12 PaaS uses structured environment promotion:

  • All TinyMCE configuration changes must be deployed.
  • Editorial experience changes must be validated in Integration.
  • Configuration should be backward-compatible with existing content.

When tightening valid elements:

  • Previously stored markup may contain unsupported tags.
  • Migration scripts may be required.
  • Testing across content repository is recommended.

Configuration changes should be treated as schema evolution.


Conclusion

Configuring rich text settings in Optimizely CMS 12 is an architectural responsibility. TinyMCE configuration determines what editors can create, what HTML is stored, and how predictable frontend rendering will be.

Using the Configuration API, scoped overrides, plugin management, and property-level control, developers can shape a structured, secure, and maintainable editorial experience.

In PaaS environments, these decisions are amplified because configuration is code-driven and deployed through CI/CD pipelines. A deliberate configuration strategy ensures long-term stability, content consistency, and alignment with frontend design systems.

Rich text is powerful — but only when controlled intentionally.