cyberangles blog

How to Turn Off HTML Encoding in CKEditor: Stop Special Characters from Being Encoded

CKEditor is one of the most popular rich text editors used in web applications, offering a user-friendly interface for creating and editing content. However, a common frustration among developers and content creators is CKEditor’s default behavior of HTML encoding special characters. For example, characters like &, <, >, or © are automatically converted to their encoded equivalents (&amp;, &lt;, &gt;, &copy;), which can break raw HTML input, technical documentation, or custom content that relies on unencoded characters.

This blog will guide you through understanding why CKEditor encodes characters, when you might need to disable this behavior, and step-by-step methods to turn off HTML encoding in both CKEditor 4 (still widely used) and CKEditor 5 (the modern, modular version). We’ll also cover troubleshooting tips and best practices to ensure security and functionality.

2026-02

Table of Contents#

  1. Understanding HTML Encoding in CKEditor
  2. Why Disable HTML Encoding?
  3. How to Disable HTML Encoding in CKEditor 4
  4. How to Disable HTML Encoding in CKEditor 5
  5. Troubleshooting Common Issues
  6. Best Practices for Disabling HTML Encoding
  7. Conclusion
  8. References

1. Understanding HTML Encoding in CKEditor#

HTML encoding is the process of converting special characters into their corresponding HTML entities to ensure they render correctly in browsers and prevent unintended behavior (e.g., breaking HTML structure). For example:

Raw CharacterEncoded Entity
&&amp;
<&lt;
>&gt;
"&quot;
©&copy;

Why CKEditor Encodes Characters by Default#

CKEditor encodes characters to:

  • Prevent XSS Attacks: Unencoded HTML/JavaScript can be exploited by attackers.
  • Ensure Valid HTML: Encoding ensures content adheres to HTML standards, avoiding rendering issues.
  • Preserve Content Integrity: Special characters (e.g., accented letters) are displayed correctly across devices.

While this is secure, it can be problematic if you need to input raw HTML, technical symbols, or custom markup.

2. Why Disable HTML Encoding?#

You may need to turn off HTML encoding in CKEditor for scenarios like:

  • Raw HTML Input: Users need to insert custom HTML snippets (e.g., embed codes, SVG, or script tags).
  • Technical Documentation: Content includes code examples (e.g., var x = 5 & y = 10) where & should remain unencoded.
  • Specialized Content: Mathematical symbols, scientific notation, or non-ASCII characters that rely on unencoded form.
  • Integration with Legacy Systems: Systems downstream expect unencoded characters and cannot decode entities.

3. How to Disable HTML Encoding in CKEditor 4#

CKEditor 4 (released in 2012) is still widely used due to its flexibility. Disabling encoding here involves configuring the HTML Writer (controls output formatting) and adjusting the Advanced Content Filter (ACF) (controls allowed HTML tags/attributes).

3.1 Configuring the HTML Writer#

The HTML Writer in CKEditor 4 handles how content is formatted and encoded. By default, it encodes basic entities (e.g., &, <), Latin entities (e.g., ñ, ü), and special entities (e.g., , ). To disable encoding, modify these settings in your CKEditor configuration file (config.js).

Step 1: Access CKEditor Configuration#

Locate or create config.js in your CKEditor installation directory (e.g., ckeditor/config.js).

Step 2: Override HTML Writer Settings#

Add the following configuration to disable encoding for specific entity types:

CKEDITOR.editorConfig = function( config ) {
  // Configure HTML Writer to disable encoding
  config.htmlWriter = {
    // Disable encoding for basic entities: &, <, >, ", '
    encodeBasicEntities: false,
    // Disable encoding for Latin entities (e.g., ñ, ü, ©)
    encodeLatinEntities: false,
    // Disable encoding for special entities (e.g., €, §, ±)
    encodeSpecialEntities: false
  };
};
  • encodeBasicEntities: Set to false to keep &, <, >, ", ' unencoded.
  • encodeLatinEntities: Set to false to preserve accented characters and Latin symbols.
  • encodeSpecialEntities: Set to false to retain special symbols like or .

3.2 Disabling Advanced Content Filter (ACF)#

CKEditor 4’s ACF strips HTML tags/attributes not explicitly allowed, even if encoding is disabled. To allow all HTML content (required for raw input), disable ACF:

CKEDITOR.editorConfig = function( config ) {
  // Disable Advanced Content Filter to allow all HTML
  config.allowedContent = true;
 
  // Optional: Allow specific tags/attributes (more secure than allowedContent: true)
  // config.allowedContent = 'p b i; a[href,target]; div; span; script[src]';
};
  • allowedContent: true: Disables ACF entirely (use cautiously—risk of XSS).
  • Custom allowedContent: Define allowed tags/attributes (e.g., p b i; a[href]) for stricter control.

3.3 Testing the Configuration#

  1. Load CKEditor in your browser.
  2. Insert a special character (e.g., & or <script>).
  3. Switch to "Source" mode (if enabled) or inspect the output HTML.
  4. Verify the character remains unencoded (e.g., & instead of &amp;).

4. How to Disable HTML Encoding in CKEditor 5#

CKEditor 5 (released in 2018) is modular and more secure by design. Encoding is handled by the editor engine, and disabling it requires configuring plugins like General HTML Support (GHS) and adjusting entity encoding settings.

4.1 Enabling General HTML Support (GHS)#

By default, CKEditor 5 restricts HTML to a safe subset. To allow raw HTML, enable the GHS plugin (included in most builds) and configure it to permit all tags/attributes:

Step 1: Install GHS (if missing)#

If using a custom build, install the GHS plugin via npm:

npm install @ckeditor/ckeditor5-html-support

Step 2: Configure GHS in Your Editor#

Update your editor initialization code to allow all HTML:

import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
import GeneralHtmlSupport from '@ckeditor/ckeditor5-html-support/src/generalhtmlsupport';
 
ClassicEditor
  .create( document.querySelector( '#editor' ), {
    plugins: [ GeneralHtmlSupport, /* ... other plugins */ ],
    htmlSupport: {
      allow: [
        {
          name: /.*/, // Allow all HTML tags
          attributes: true, // Allow all attributes
          classes: true, // Allow all classes
          styles: true // Allow all styles
        }
      ]
    }
  } )
  .catch( error => {
    console.error( error );
  } );

This allows the editor to accept raw HTML input without stripping tags.

4.2 Controlling Entity Encoding#

CKEditor 5 encodes non-ASCII characters by default (e.g., ©&#169;). To disable this, set config.entities = false:

ClassicEditor
  .create( document.querySelector( '#editor' ), {
    entities: false, // Disable encoding for non-ASCII entities
    // ... other config (e.g., htmlSupport)
  } )
  .catch( error => {
    console.error( error );
  } );

Note: entities: false only disables encoding for non-ASCII characters. Basic entities (&, <, >, ", ') are still encoded for security and cannot be disabled via config.

4.3 Post-Processing for Basic Entities#

If you need to unencode basic entities (e.g., &amp;&) in CKEditor 5 output, you’ll need to post-process the data after retrieving it from the editor. Use a library like he (HTML entity encoder/decoder) to decode entities:

Step 1: Install he#

npm install he

Step 2: Decode Output#

After getting the editor’s data, decode entities with he.decode():

import he from 'he';
 
// Get raw encoded data from CKEditor 5
const encodedData = editor.getData();
 
// Decode basic entities (e.g., &amp; → &)
const decodedData = he.decode( encodedData );
 
// Use decodedData in your application
console.log( decodedData ); // Now contains unencoded &, <, >, etc.

5. Troubleshooting Common Issues#

Encoding Still Occurs#

  • CKEditor 4: Ensure htmlWriter settings are correctly applied and allowedContent is not stripping tags.
  • CKEditor 5: Confirm entities: false is set and use post-processing for basic entities.

Content Is Stripped#

  • ACF/GHS Issues: In CKEditor 4, set allowedContent: true (temporarily) to test if ACF is the culprit. In CKEditor 5, verify htmlSupport.allow permits your tags.

XSS Warnings#

  • If using allowedContent: true (CKEditor 4) or permissive htmlSupport (CKEditor 5), ensure content is only edited by trusted users and sanitize server-side.

6. Best Practices for Disabling HTML Encoding#

  • Limit to Trusted Users: Only disable encoding for admin/editor roles; never for public users (risk of XSS).
  • Server-Side Sanitization: Use libraries like DOMPurify (JavaScript) or bleach (Python) to sanitize output before storage/display.
  • Avoid Overly Permissive Rules: In CKEditor 4, use allowedContent with specific tags/attributes instead of true. In CKEditor 5, restrict htmlSupport.allow to required tags.
  • Test Across Browsers: Encoding behavior may vary; test content in Chrome, Firefox, and Safari.
  • Keep CKEditor Updated: Use the latest version to patch security vulnerabilities.

7. Conclusion#

Disabling HTML encoding in CKEditor requires careful configuration of the HTML Writer (CKEditor 4) or General HTML Support (CKEditor 5), combined with post-processing for basic entities (CKEditor 5). While this unlocks flexibility for raw HTML and special content, prioritize security by limiting access to trusted users and sanitizing output server-side.

By following the steps above, you can ensure CKEditor preserves unencoded characters while maintaining control over content integrity.

8. References#