CKEditor embed integration

Insert rich embeds from any URL in CKEditor 5 using OpenGraph.io oEmbed: native providers when available, hosted fallback cards otherwise.

Architecture

Proxy oEmbed requests through your application server. CKEditor should receive only the sanitized html snippet returned by OpenGraph.io.

Use source to distinguish native iframes from OpenGraph-hosted fallback cards in your editor UI (e.g. badge or tooltip for editors).

CKEditor 5 custom plugin (sketch)

Plugin command
class OgEmbedCommand extends Command {
  async execute(url) {
    const res = await fetch('/api/embed-proxy', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ url }),
    });
    const data = await res.json();
    if (!data.html) return;
    this.editor.model.change(writer => {
      const viewFragment = this.editor.data.processor.toView(data.html);
      const modelFragment = this.editor.data.toModel(viewFragment);
      this.editor.model.insertContent(modelFragment);
    });
  }
}

Media embed + fallback

CKEditor's built-in Media Embed plugin handles oEmbed providers it recognizes. For URLs outside that set, use OpenGraph.io as the universal resolver. The fallback og_frame tier covers blog posts, docs, product pages, and niche sites.

Example request
curl "https://opengraph.io/api/3.0/oembed?url=https%3A%2F%2Fexample.com%2Fpost&app_id=YOUR_APP_ID&maxwidth=720"

Theme and template (fallback cards)

When embedding fallback cards, pass appearance options to match your editor chrome:

&theme=light&template=compact&always_og_frame=true

See oEmbed API docs for full parameter reference.

See also