Skip to content

Email plugin: scope additional improvements for v3.7 beyond the React Email migration #4775

Description

@michaelbromley

Context

PR #4766 (move mjml to optional peer dep in @vendure/email-plugin) was closed in favour of a fuller plan: deprecate HandlebarsMjmlGenerator and ship React Email (@react-email/render + @react-email/components) as the new default generator. Full rationale (worm-threat model favours dep-count, MJML DX showing its age, half-measure vs full replacement) is in the closing comment, tracked under #4761.

Planned sequence for the generator change:

  • v3.7: Add ReactEmailGenerator alongside HandlebarsMjmlGenerator. Ship Vendure's default templates in JSX form. Mark HandlebarsMjmlGenerator as @deprecated and add a migration guide.
  • v3.8 / v4.0: Switch default to ReactEmailGenerator. mjml becomes an optional peer dependency.
  • v4.x: Remove HandlebarsMjmlGenerator entirely.

Why this issue

If we're already opening up @vendure/email-plugin in v3.7 — touching the generator API, default templates, docs, and the user-facing surface — it's a good moment to consider what else this plugin should be doing in a modern admin/dashboard context. The plugin has barely changed shape since it was first shipped, while the platform around it (notably the new React Dashboard) has moved on considerably.

The goal of this issue is to scope and decide which of the following ship in v3.7 alongside the React Email work.

Ideas to discuss

1. Dashboard Views

The new React Dashboard makes it cheap to add first-class views for plugins. The email plugin has plenty of surface that would benefit:

  • Templates view — list configured EmailEventHandlers, the events they listen to, the resolved template(s), and whether each is currently enabled per-channel.
  • Preview view — render a template against realistic sample data (Order, Customer, etc.) and view the resulting HTML and subject inline, without having to trigger the actual event. Hot-reload on template edits in dev mode.
  • Settings view — surface plugin config (transport, from address, attachment limits) read-only, with copy-paste examples for editing in code.

Open questions:

  • Where do Dashboard Views for core plugins live — in the plugin package itself, or under @vendure/dashboard?
  • Permissions model — new ReadEmailTemplates permission, or piggyback on ReadSettings?
  • Read-only vs editable templates (the latter would imply runtime template overrides, which is a much bigger feature).

2. Email delivery log

Today the plugin emits to a configurable transport (SMTP, SES, file, etc.) and that's it. There's no built-in record of what was sent, to whom, at what time, with what outcome.

A persisted delivery log would give:

  • An admin a way to confirm "did the customer receive the order confirmation?" without diving into transport-level logs.
  • Support teams a self-serve way to resend a failed email.
  • A natural foundation for retries, bounce handling, and suppression lists in future.

Open questions:

  • Storage modelEmailDeliveryLog entity in @vendure/email-plugin, opt-in via config? Retention policy? Channel-scoped?
  • Fields — recipients, subject, template name, event type, status (queued / sent / failed / bounced), timestamps, transport response payload?
  • API — admin GraphQL extension, paginated list + filters, resendEmail mutation?
  • Dashboard View to consume it (overlaps with item 1).

3. Dev Mailbox built into dashboard

In development we currently default to the file transport, which writes a .json per email to disk. It works, but the DX is fiddly — most devs end up running mailpit / mailhog / maildev in Docker just to inspect what their templates rendered to.

If the dashboard exposed a Dev Mailbox view backed by the file transport (or a new in-memory / SQLite-backed dev transport), the framework would ship a working "see your emails" experience out of the box. No extra container, no extra port, no extra docs page.

Open questions:

  • Reuse the existing file transport as the data source, or ship a dedicated DevMailboxTransport that backs the view directly?
  • Auto-enable when NODE_ENV !== 'production', or always opt-in?
  • Live updates (WebSocket / polling) when a new email arrives?
  • Is this just the delivery-log view (item 2) plus a development-mode flag, or a distinct feature?

Scope decision

Each of the three above is independent and could ship without the others, but they share infrastructure (Dashboard View pattern, delivery-log entity, transport contract). Worth agreeing the dependency order before parallelising:

  • A Dashboard View is a prerequisite for the other two having any UI surface.
  • The delivery log gives the Dev Mailbox most of its data model for free.
  • The Dev Mailbox is the highest-leverage DX win and could be carved out and shipped on its own once the dashboard-view pattern + transport contract are settled.

Realistic v3.7 cut might be: React Email migration + a Templates / Preview Dashboard View + the delivery-log entity (without the resend mutation), with the Dev Mailbox following as a v3.8 follow-up. To be discussed.

Related

Metadata

Metadata

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions