# HTML embed

The HTML embed feature lets you embed any HTML snippet in your content. The feature is meant for more advanced users who want to directly interact with HTML fragments.

> **Unlock this feature with selected CKEditor Plans**
>
> Try all premium features – no credit card needed.
>
> [Sign up for a free trial ](https://portal.ckeditor.com/checkout?plan=free)[Select a Plan](https://ckeditor.com/pricing/)

<a id="demo">

## Demo

Use the HTML embed toolbar button in the editor below to see the plugin in action. Click the “Preview editor data” button under the editor to preview the editor content, including the embedded HTML.

<!-- AI-AGENT-NOTE: An interactive demo is embedded here but is not represented in this Markdown file. If you need to see it in action, open this page in a browser (e.g. via a browser-automation MCP like Chrome DevTools or Playwright), or let the user know a live demo is available on this page. -->

This demo presents a limited set of features. Visit the [feature-rich editor example](../../examples/builds-custom/full-featured-editor.md) to see more in action.

<a id="demo-content-preview">

### Demo content preview

<a id="preview-data-container">

<a id="additional-feature-information">

## Additional feature information

This feature lets you embed any HTML code and bypass CKEditor 5’s filtering mechanisms. You can use it to enrich content produced by CKEditor 5 with fragments of HTML that are not supported by any other CKEditor 5 feature.

Some examples of content that you can embed thanks to the HTML embed feature:

* Analytics code (that usually requires embedding `<script>` elements).
* Social page widgets (that also require embedding `<script>` elements).
* Content embeddable by `<iframe>` elements.
* HTML media elements such as `<audio>` and `<video>`.
* HTML snippets produced by external tools (for example, reports or charts).
* Interactive content that requires a combination of rich HTML and scripts.

We recommended using the [media embed](../media-embed/media-embed.md) feature for embeddable media that this feature supports. You can use the HTML embed feature to handle the remaining content.

> **Warning**
>
> Read the [Security](#security) section before installing this plugin.
>
> Incorrect configuration may **lead to security issues**.

<a id="installation">

## Installation

After [installing the editor](../../getting-started/installation/cloud/quick-start.md), add the feature to your plugin list and toolbar configuration:

**NPM**

```js
import { ClassicEditor, HtmlEmbed } from 'ckeditor5';

ClassicEditor
	.create( {
		licenseKey: '<YOUR_LICENSE_KEY>', // Or 'GPL'.
		plugins: [ HtmlEmbed, /* ... */ ],
		toolbar: [ 'htmlEmbed', /* ... */ ],
		htmlEmbed: {
			// Configuration.
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

**CDN**

```js
const { ClassicEditor, HtmlEmbed } = CKEDITOR;

ClassicEditor
	.create( {
		licenseKey: '<YOUR_LICENSE_KEY>',
		plugins: [ HtmlEmbed, /* ... */ ],
		toolbar: [ 'htmlEmbed', /* ... */ ],
		htmlEmbed: {
			// Configuration.
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

<a id="configuration">

## Configuration

<a id="content-previews">

### Content previews

The feature is by default configured to not show previews of the HTML snippets. You can enable the previews by setting the [`config.htmlEmbed.showPreviews`](../../api/module_html-embed_htmlembedconfig-HtmlEmbedConfig.md#member-showPreviews) option to `true`.

However, by showing previews of the embedded HTML snippets, you expose the users of your system to the **risk of executing malicious JavaScript code inside the editor**. Therefore, it is highly recommended to plug in some HTML sanitizer that will strip the malicious code from the created snippets before rendering their previews. You can plug in the sanitizer by defining the [`config.htmlEmbed.sanitizeHtml`](../../api/module_html-embed_htmlembedconfig-HtmlEmbedConfig.md#member-sanitizeHtml) option.

```js
ClassicEditor
	.create( {
		// ... Other configuration options ...
		htmlEmbed: {
			showPreviews: true,
			sanitizeHtml: ( inputHtml ) => {
				// Strip unsafe elements and attributes, for example:
				// the `<script>` elements and `on*` attributes.
				const outputHtml = sanitize( inputHtml );

				return {
					html: outputHtml,
					// true or false depending on whether the sanitizer stripped anything.
					hasChanged: true
				};
			}
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

Currently, the [feature does not execute `<script>` tags](https://github.com/ckeditor/ckeditor5/issues/8326) so the content that requires executing JavaScript to generate a preview will not show in the editor. However, other JavaScript code, for example, used in `on*` observers and `src="javascript:..."` attributes will be executed. You still need to enable the sanitizer.

Displaying raw HTML previews can execute malicious JS (for example via `onclick` or `javascript:`) in your site’s context. Read more about the security aspect in the next section.

<a id="security">

### Security

If you configure the HTML embed feature to [show content previews](#content-previews), the HTML that the user inserts into the HTML embed widget is then rendered back to the user. \*\*If the HTML was rendered as-is, **the browser would execute any JavaScript code included in these HTML snippets in the context of your website**.

This, in turn, is a plain security risk. The HTML provided by the user might be mistakenly copied from a malicious website. It could also end up in the user’s clipboard (as it would usually be copied and pasted) by any other means.

You can instruct some advanced users to never paste HTML code from untrusted sources. However, in most cases, it is highly recommended to secure the system by configuring the HTML embed feature to use an HTML sanitizer and, optionally, by setting strict Content Security Policy (CSP) rules.

> **Note**
>
> The tricky part is that some HTML snippets require executing JavaScript to render any meaningful previews (for example, Facebook embeds). Some, in turn, do not make sense to execute (like analytics code).
>
> Therefore, when configuring the sanitizer and CSP rules, you can take these situations into consideration and for instance, allow `<script>` tags pointing only to certain domains (like a trusted external page that requires JavaScript).

<a id="sanitizer">

#### Sanitizer

> **Important**
>
> Scripts may not run in the `<script>` tags in previews, but inline JS in attributes will. Always sanitize or limit allowed sources to stay safe!

The [`config.htmlEmbed.sanitizeHtml`](../../api/module_html-embed_htmlembedconfig-HtmlEmbedConfig.md#member-sanitizeHtml) option allows plugging an external sanitizer.

Some popular JavaScript libraries that you can use include [`sanitize-html`](https://www.npmjs.com/package/sanitize-html) and [`DOMPurify`](https://www.npmjs.com/package/dompurify).

The default settings of these libraries usually strip all potentially malicious content including `<iframe>`, `<video>`, or similar elements and JavaScript code coming from trusted sources. You may need to adjust their settings to match your needs.

When `showPreviews = true`, use libraries like `DOMPurify` or `sanitize-html` to prevent XSS Attacks. Sample code may look similar to this:

```js
sanitizeHtml: inputHtml => {
  const safe = DOMPurify.sanitize(inputHtml, {...});
  return { html: safe, hasChanged: safe !== inputHtml };
}
```

Adjust allowed tags/attributes (for example: permit `iframe` only from trusted domains) to balance functionality and safety. Consider pairing this with CSP for stronger security. Check the [Content previews](#content-previews) and [Security](#security) sections of this guide for more details.

<a id="csp">

#### CSP

In addition to sanitizing content, you can utilize the built-in browser mechanism called [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP). By using CSP, the browser recognizes allowed sources and methods of executing JavaScript code. It also allows including other resources such as style sheets, images, and fonts. Check out the dedicated [Content Security Policy](../../getting-started/setup/csp.md) setup guide.

<a id="related-features">

## Related features

CKEditor 5 supports a wider range of embed and code features, including:

* [Media embed](../media-embed/media-embed.md) – Insert embeddable media such as YouTube or Vimeo videos and tweets into your rich text content.
* [Code blocks](../code-blocks.md) – Insert longer, multiline listings of pre-formatted code with a programming language assigned.
* [General HTML Support](general-html-support.md) – Enable HTML features (elements, attributes, classes, styles) that are not supported by other dedicated CKEditor 5 plugins.

<a id="common-api">

## Common API

The [`HtmlEmbed`](../../api/module_html-embed_htmlembed-HtmlEmbed.md) plugin registers:

* The UI button component (`'htmlEmbed'`).
* The `'htmlEmbed'` command implemented by [`HtmlEmbedCommand`](../../api/module_html-embed_htmlembedcommand-HtmlEmbedCommand.md).

You can execute the command using the [`editor.execute()`](../../api/module_core_editor_editor-Editor.md#function-execute) method:

```js
// Inserts an empty HTML embed.
editor.execute( 'htmlEmbed' );

// Inserts an HTML embed with some initial content.
editor.execute( 'htmlEmbed', '<b>Initial content</b>.' );

// Updates the content of a selected HTML embed.
editor.execute( 'htmlEmbed', '<b>New content.</b>' );
```

> **Note**
>
> We recommend using the official [CKEditor 5 inspector](../../framework/development-tools/inspector.md) for development and debugging. It will give you tons of useful information about the state of the editor such as internal data structures, selection, commands, and many more.

<a id="contribute">

## Contribute

The source code of the feature is available on GitHub at <https://github.com/ckeditor/ckeditor5/tree/master/packages/ckeditor5-html-embed>.

---

Full index of the CKEditor 5 documentation: [llms.txt](../../../llms.txt)
