cartwright
Features

Marketing automations

Emit lifecycle events (welcome, abandoned-cart, post-purchase) to Resend Automations — consent-gated, flag-off by default.

The marketingAutomations feature drives lifecycle email sequences — welcome, abandoned-cart recovery, post-purchase — through Resend Automations.

Cartwright's job is small and self-contained: it emits events at the right moments. Resend runs the actual sequences (timing, steps, content) you wire in the Resend dashboard. Cartwright never owns the drip content or scheduling. Source: lib/marketing/automations.ts.

Turning it on

Set a Resend API key (/admin/integrations, or RESEND_API_KEY) — the same key Cartwright already uses for transactional email.
Enable marketingAutomations in /admin/features (or brand.features.marketingAutomations = true). Default off.
In the Resend dashboard, create one Automation per sequence, each with a trigger whose event name matches the table below.

Without a Resend key the feature is inert — every emit is a no-op.

Events Cartwright emits

Event nameFired whenPayload
cartwright.user.createda customer registers{ name }
cartwright.cart.abandonedthe abandoned-cart cron finds a logged-in cart idle ≥ 24h{ cartUrl, itemCount, items }
cartwright.order.placedan order is marked paid (Stripe webhook){ orderId, totalDkk, currency, itemCount }

Resend auto-creates the contact from the event's email and runs the matching automation. Use the payload fields in your templates.

Marketing events fire only for customers with marketing consent — defined as a confirmed newsletter subscriber (Subscriber.status === "confirmed"), including order.placed. The whole policy lives in one function, hasMarketingConsent(email) — change it there to broaden the rule. Cookie consent is per-browser and can't address an email server-side, so the newsletter opt-in is the gate.

Relationship to the abandoned-cart cron

With marketingAutomations on, the existing abandonedCart cron emits cartwright.cart.abandoned (Resend runs a multi-step drip) instead of sending its own single recovery email — no double send.

abandonedCartmarketingAutomationsBehavior
onoffDirect single recovery email
offonEmit cart.abandoned → Resend drip
ononEmit cart.abandoned → Resend drip (no direct send)
offoffCron no-ops

Resend-specific by design — Resend is already the transport. There is no ESP-agnostic event bus.

On this page