CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ckeditor--ckeditor5-html-embed

HTML embed feature for CKEditor 5 enabling users to insert arbitrary HTML snippets as interactive widgets

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

index.mddocs/

CKEditor 5 HTML Embed

CKEditor 5 HTML Embed is a feature plugin that enables users to insert arbitrary HTML snippets directly into the editor as interactive widgets. It provides a secure way to embed custom HTML content while maintaining the editor's WYSIWYG experience through configurable sanitization and preview capabilities.

Package Information

  • Package Name: @ckeditor/ckeditor5-html-embed
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @ckeditor/ckeditor5-html-embed

Core Imports

import { HtmlEmbed, HtmlEmbedEditing, HtmlEmbedUI, HtmlEmbedCommand } from '@ckeditor/ckeditor5-html-embed';
import type { HtmlEmbedConfig, HtmlEmbedSanitizeOutput, _RawHtmlEmbedApi } from '@ckeditor/ckeditor5-html-embed';
import { Command, Plugin, type Editor } from 'ckeditor5/src/core.js';
import { Widget } from 'ckeditor5/src/widget.js';

For CommonJS:

const { HtmlEmbed, HtmlEmbedEditing, HtmlEmbedUI, HtmlEmbedCommand } = require('@ckeditor/ckeditor5-html-embed');

Basic Usage

import { ClassicEditor } from '@ckeditor/ckeditor5-editor-classic';
import { HtmlEmbed } from '@ckeditor/ckeditor5-html-embed';

ClassicEditor
  .create(document.querySelector('#editor'), {
    plugins: [HtmlEmbed],
    toolbar: ['htmlEmbed'],
    htmlEmbed: {
      showPreviews: true,
      sanitizeHtml: (inputHtml) => ({
        html: inputHtml, // Implement proper sanitization
        hasChanged: false
      })
    }
  })
  .then(editor => {
    // Editor ready with HTML embed feature
    const htmlEmbedCommand = editor.commands.get('htmlEmbed');
    
    // Insert HTML embed programmatically
    htmlEmbedCommand.execute('<div>Custom HTML content</div>');
  });

Architecture

The HTML Embed feature is built around several key components:

  • HtmlEmbed Plugin: Main orchestrator that combines editing, UI, and widget functionality
  • HtmlEmbedEditing: Handles model schema, data conversion, and command registration
  • HtmlEmbedUI: Provides toolbar buttons and user interface elements
  • HtmlEmbedCommand: Executes HTML embed insertion and update operations
  • Widget Integration: Uses CKEditor's widget system for proper selection and editing behavior
  • Sanitization: Configurable HTML sanitization for security when previews are enabled

Types

Base Classes

// Base classes from CKEditor 5 core
class Plugin {
  // Base plugin class
}

class Command {
  // Base command class
}

class Widget {
  // Widget functionality
}

Capabilities

Main HTML Embed Plugin

The primary plugin class that orchestrates the HTML embed feature.

class HtmlEmbed extends Plugin {
  /**
   * Required plugins for HTML embed functionality
   */
  static readonly requires: readonly [typeof HtmlEmbedEditing, typeof HtmlEmbedUI, typeof Widget];
  
  /**
   * Plugin name identifier
   */
  static readonly pluginName: 'HtmlEmbed';
  
  /**
   * Indicates this is an official CKEditor plugin
   */
  static readonly isOfficialPlugin: true;
}

HTML Embed Editing

Handles the editor model, schema, data conversion, and command registration.

class HtmlEmbedEditing extends Plugin {
  /**
   * Plugin name identifier
   */
  static readonly pluginName: 'HtmlEmbedEditing';
  
  /**
   * Indicates this is an official CKEditor plugin
   */
  static readonly isOfficialPlugin: true;
  
  /**
   * Creates a new instance of HtmlEmbedEditing plugin
   * @param editor - The editor instance
   */
  constructor(editor: Editor);
  
  /**
   * Initializes the editing functionality - sets up model schema, 
   * data conversion, and registers the htmlEmbed command
   */
  init(): void;
}

HTML Embed UI

Provides user interface components including toolbar buttons and menu items.

class HtmlEmbedUI extends Plugin {
  /**
   * Plugin name identifier
   */
  static readonly pluginName: 'HtmlEmbedUI';
  
  /**
   * Indicates this is an official CKEditor plugin
   */
  static readonly isOfficialPlugin: true;
  
  /**
   * Creates a new instance of HtmlEmbedUI plugin
   * @param editor - The editor instance
   */
  constructor(editor: Editor);
  
  /**
   * Initializes UI components - registers toolbar and menu bar buttons
   */
  init(): void;
}

HTML Embed Command

Command implementation for inserting and updating HTML embed elements.

class HtmlEmbedCommand extends Command {
  /**
   * Flag indicating whether the command can be executed
   */
  readonly isEnabled: boolean;
  
  /**
   * Current value of selected HTML embed element, or null if none selected
   */
  readonly value: string | null;
  
  /**
   * Creates a new instance of HtmlEmbedCommand
   * @param editor - The editor instance
   */
  constructor(editor: Editor);
  
  /**
   * Updates command state and value based on current selection
   */
  refresh(): void;
  
  /**
   * Executes the command to insert new HTML embed or update existing one
   * @param value - HTML content to insert or update with (optional)
   */
  execute(value?: string): void;
}

Usage Example:

// Get the command instance
const htmlEmbedCommand = editor.commands.get('htmlEmbed');

// Check if command is enabled
if (htmlEmbedCommand.isEnabled) {
  // Insert new HTML embed
  htmlEmbedCommand.execute('<iframe src="https://example.com"></iframe>');
}

// Check current HTML embed value (if selection is on HTML embed)
const currentValue = htmlEmbedCommand.value;
if (currentValue) {
  // Update existing HTML embed
  htmlEmbedCommand.execute('<div>Updated content</div>');
}

Configuration

Configuration interface for customizing HTML embed behavior.

interface HtmlEmbedConfig {
  /**
   * Whether to render previews of embedded HTML (default: false)
   */
  showPreviews?: boolean;
  
  /**
   * Function to sanitize HTML for preview rendering
   */
  sanitizeHtml?: (html: string) => HtmlEmbedSanitizeOutput;
}

Configuration Example:

ClassicEditor.create(editorElement, {
  htmlEmbed: {
    showPreviews: true,
    sanitizeHtml: (inputHtml) => {
      // Implement sanitization logic here
      const sanitizedHtml = sanitizeHtmlContent(inputHtml);
      return {
        html: sanitizedHtml,
        hasChanged: sanitizedHtml !== inputHtml
      };
    }
  }
});

Sanitization Output

Structure returned by the sanitization function.

interface HtmlEmbedSanitizeOutput {
  /**
   * Sanitized HTML that will be rendered in the preview
   */
  html: string;
  
  /**
   * Flag indicating if sanitization modified the input
   */
  hasChanged: boolean;
}

Internal Widget API

Internal API exposed on HTML embed widgets for programmatic control.

interface _RawHtmlEmbedApi {
  /**
   * Switch widget to editable mode
   */
  makeEditable(): void;
  
  /**
   * Save changes to widget content
   */
  save(newValue: string): void;
  
  /**
   * Cancel editing and revert to non-editable mode
   */
  cancel(): void;
}

Note: This is an internal API (prefixed with underscore) and should not be used in regular implementations.

Security Considerations

The HTML Embed feature includes important security considerations:

  • Default Sanitization: The default sanitization function only logs warnings and doesn't actually sanitize content
  • XSS Prevention: When showPreviews is enabled, implement proper sanitizeHtml function to prevent XSS vulnerabilities
  • Content Storage: HTML content is stored and rendered as-is in the data output
  • Recommendation: Always implement custom sanitization when enabling preview functionality

Secure Configuration Example:

import sanitizeHtml from 'sanitize-html';

ClassicEditor.create(editorElement, {
  htmlEmbed: {
    showPreviews: true,
    sanitizeHtml: (inputHtml) => {
      const cleanHtml = sanitizeHtml(inputHtml, {
        allowedTags: ['div', 'span', 'p', 'br'],
        allowedAttributes: {
          'div': ['class'],
          'span': ['class']
        }
      });
      
      return {
        html: cleanHtml,
        hasChanged: cleanHtml !== inputHtml
      };
    }
  }
});

Model and Data Format

The HTML Embed feature uses the following data structures:

  • Model Element: rawHtml - Block-level element in the CKEditor model
  • Model Attribute: value - Stores the HTML content as a string
  • Data Format: Converts between div.raw-html-embed elements and rawHtml model elements
  • Schema: Inherits from $blockObject and allows the value attribute

Dependencies

Required CKEditor 5 packages:

  • @ckeditor/ckeditor5-core - Core plugin and command classes
  • @ckeditor/ckeditor5-ui - UI components and button implementations
  • @ckeditor/ckeditor5-widget - Widget functionality for proper selection behavior
  • @ckeditor/ckeditor5-utils - Utility functions
  • @ckeditor/ckeditor5-icons - Icon resources for UI components

Install with Tessl CLI

npx tessl i tessl/npm-ckeditor--ckeditor5-html-embed

docs

index.md

tile.json