Hulo Global
Plugins

Email Tracking

See exactly what every transactional email does — opens, clicks, bounces, suppressions.

What it does

Built for production from day one.

Drop-in tracker for every email your Vendure server sends. Wraps the `@vendure/email-plugin` pipeline plus a service for ad-hoc sends. Logs every send, click and open with full history. Suppression list auto-handles hard bounces and complaints. Per-template open rates, CSV export, device + client detection on every open.

Open + click pixel-and-redirect tracking

Per-event 1×1 pixel for opens, per-link redirector for clicks. Bot UAs are flagged separately.

Full open + click history per email

Last 50 opens and clicks per row with timestamp, IP, user-agent and parsed client (Gmail web, Outlook desktop, Apple Mail iOS …).

Suppression list

Hard bounces and complaints auto-add to the suppression table. Subsequent sends are silently skipped and logged as `status=suppressed`.

Per-template analytics

Open rate, CTR, click-to-open ratio and bounce rate per email type — order-confirmation, OTP, invoice, password-reset and your custom types.

Bounce + complaint webhook

POST DSN events to `/email-track/bounce` from your postmaster integration. Both bounce types tracked.

Admin UI: Email Log + per-customer Emails tab

Filter by recipient, customer, order, status, type, date range. Expand any row for the full event timeline.

CSV export

`/email-track/log/export.csv` returns up to 50k rows with the same filter shape as the list view.

Works with any SMTP transport

Gmail, SES, SendGrid, Postmark, Mailgun, raw SMTP. Just plug `TrackingEmailSender()` into your email-plugin config.

Install

Three steps, five minutes.

Add the package

Or run the one-line installer that does steps 1–3 for you:

curl -sSL https://huloglobal.com/vendure-plugins/email-tracking/install.sh | bash

Prefer to do it by hand?

yarn add @huloglobal/vendure-plugin-email-tracking

Register it

In your vendure-config.ts:

# vendure-config.ts import { EmailTrackingPlugin } from '@huloglobal/vendure-plugin-email-tracking'; export const config: VendureConfig = { plugins: [ EmailTrackingPlugin.init({ publicBaseUrl: 'https://shop.example.com', licenceKey: process.env.HULO_LICENCE_KEY_EMAIL_TRACKING, }), // ... your other plugins ], };

Run the migration

The plugin adds its own table(s). Generate + run the migration like any other:

yarn migration:generate AddEmailTrackingPluginTables yarn migration:run

That's it. The admin UI tab appears immediately. Without a licence key the plugin runs in a degraded evaluation mode — fine for trying things out. Buy a key →

HTTP endpoints

Every route exposed.

GET/email-track/open/:id.gifPixel — logs an open then serves a 1×1 GIF
GET/email-track/click/:id?u=<url>Click redirector — logs then 302s to the original URL
POST/email-track/bounceBounce / complaint webhook — DSN bridge
GET/email-track/logAdmin: paginated log with filters
GET/email-track/log/summaryAdmin: status totals tile
GET/email-track/log/:idAdmin: full detail (incl. opens + clicks arrays)
GET/email-track/log/stats/by-templateAdmin: per-template aggregates (open / click rate, CTR)
GET/email-track/log/export.csvAdmin: CSV export
GET/email-track/suppressionAdmin: list suppression entries
POST/email-track/suppressionAdmin: manually add a recipient
DELETE/email-track/suppression/:recipientAdmin: lift a suppression

FAQ

Common questions.

How do I get a licence key?

Buy here — Stripe Checkout, monthly or lifetime. You'll receive the JWT key by email; set it as HULO_LICENCE_KEY_EMAIL_TRACKING in your .env.

Does it work without a key?

Yes — the plugin boots in a degraded "evaluation" mode. You can install, configure, and inspect the admin UI before committing.

Where is data stored?

In your Vendure database. The plugin adds its own tables via a migration — your data never leaves your server.

Will it survive a Vendure upgrade?

It targets Vendure 3.x (compatibility set to ^3.0.0). Major version bumps will be tested against new Vendure releases.

Ready to ship?

Buy a key, drop the plugin in, ship today.