Angular’s component lifecycle maps cleanly onto init()/destroy(): mount in ngAfterViewInit, once the template’s ViewChild is guaranteed to exist, and tear down in ngOnDestroy.

Installation

npm install @maildeno/editor

The editor component

// editor.component.ts
import {
  Component,
  ElementRef,
  ViewChild,
  AfterViewInit,
  OnDestroy,
} from "@angular/core";
import { init, type EditorHandle } from "@maildeno/editor/init";
import { HttpClient } from "@angular/common/http";

@Component({
  selector: "app-email-editor",
  standalone: true,
  template: `<div #container></div>`,
})
export class EmailEditorComponent implements AfterViewInit, OnDestroy {
  @ViewChild("container") containerRef!: ElementRef<HTMLDivElement>;
  private handle: EditorHandle | null = null;

  constructor(private http: HttpClient) {}

  async ngAfterViewInit(): Promise<void> {
    this.handle = await init({
      container: this.containerRef.nativeElement,
      capabilities: { export: ["html", "mjml", "json"] },
      onSave: (payload: { templateId: string | null }) => {
        console.log("Saved", payload);
        const target = handle?.getHtml(); // handle?.getReactEmail() or handle?.getMjml()
        console.log(target);
      },
      onSendTestEmail: async ({ to, subject, html }) => {
        await fetch("/api/send-test", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ to, subject, html }),
        });
      },
    });
  }

  ngOnDestroy(): void {
    this.handle?.destroy();
    this.handle = null;
  }
}

ViewChild isn’t resolved until after the first change-detection pass, which is exactly what AfterViewInit guarantees — mounting any earlier would hit a null container.

A note on zones

@maildeno/editor manages its own internal Vue reactivity inside a shadow root; it doesn’t run through Angular’s change detection, and it doesn’t need to. You generally won’t need NgZone.runOutsideAngular() here — the editor isn’t triggering Angular change-detection cycles on every internal keystroke the way, say, a manually-driven third-party chart redraw might.

Where to go next