Zindua

Zindua for React Email

Nodemailer, SendGrid, SES: keep your provider. Host multilingual templates, interpolate {{vars}}, and send with @zindua/sdk v1.4.0. Guide v1.0.0.

npm install @zindua/sdk@1.4.0 @zindua/react-email react-email

Keep your provider

Connect the same SendGrid, SES, SMTP, or Gmail account under Service. Zindua orchestrates; it does not become your ESP.

Import React Email HTML

render() locally, then push bodyHtml with the CLI or SDK. TipTap stays the dashboard editor; no .tsx on our servers.

One send API

Replace transporter.sendMail({ html }) with zindua.send({ template, variables, lang }). Same slug for WhatsApp OTP.

i18n + ops built-in

Locales, {{var|fallback}}, verify-before-send, logs, and failover without rebuilding them around Nodemailer.

@zindua/react-email

pushReactEmail() renders your component and upserts a hosted template version in one call.

CLI companion

zindua templates push and doctor before you swap sendMail in production.

Quick start

Install, push, send

Pick a step. The TypeScript snippet updates. React Email to first hosted send.

terminal
npm install @zindua/sdk@1.4.0 @zindua/react-email react-email # .envZINDUA_API_KEY=znd_test_your_key_here
Setup

Step by step

01

Connect Service

Dashboard → Project → Service. Link SendGrid, Amazon SES, custom SMTP, Gmail, or Outlook: the same stack you already use with React Email.

02

Install packages

npm install @zindua/sdk@1.4.0 @zindua/react-email. Keep react-email for local authoring.

03

Push a template

render() or pushReactEmail() with {{tokens}} in the HTML. Upsert by slug + lang via SDK or CLI.

04

Swap the send call

Delete local transporter wiring. Call zindua.send with template slug + variables. Delivery still leaves through your provider.

API

Methods

Template upsert + render on top of the standard send API.

MethodEndpointDescription
send()POST /sendQueue email or WhatsApp message
upsertTemplate()PUT /templates/{slug}/versions/{lang}Create or update a hosted HTML version
renderTemplate()POST /templates/renderInterpolate subject/html without sending
getTemplates()GET /templatesSynced slugs, langs, variables
Migration

An API path for any provider

Select Nodemailer, SendGrid, or SES. Toggle Before / After to see the swap to zindua.send.

before-nodemailer.tsx
import { render } from "react-email";import nodemailer from "nodemailer";import { WelcomeEmail } from "./emails/welcome"; const transporter = nodemailer.createTransport({  host: "smtp.example.com",  port: 465,  secure: true,  auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS },}); const html = await render(  <WelcomeEmail name="Ada" appName="Acme" />); await transporter.sendMail({  from: "you@example.com",  to: "user@gmail.com",  subject: "Welcome",  html,});
CLI

Push HTML without the helper

Export from React Email, then templates push.

# After react-email render / export to ./welcome.html
npx @zindua/cli@1.2.0 templates push \
  --slug welcome \
  --lang en \
  --subject "Welcome {{name}}" \
  --html ./welcome.html \
  --default
Environment

Variables

VariableRequiredExampleNotes
ZINDUA_API_KEYYesznd_test_xxxxxxxxxxxxxxxxxxxxxxxxFrom Dashboard → Projects
ZINDUA_API_BASE_URLNohttps://zindua.run/api/v1Optional API override

Test first with the CLI

Smoke test your API key before swapping sendMail in production.

npx @zindua/cli@latest doctor

Ship the migration

Connect Service, push one template, replace sendMail with zindua.send.