Files
skills/docs/communication/emails/email-templates/src/templates/invoice/invoice.md
2026-05-29 08:20:56 +01:00

3.3 KiB
Raw Blame History

invoice

(no submodules)

Purpose

The invoiceTemplate is the receipt / invoice / order-confirmation email. It renders a heading carrying the invoice number, a metadata line (date, optional due date), a line-items table with description / quantity / unit-price / total columns, a subtotal-tax-total summary, and an optional "Pay Now" CTA when paymentUrl is supplied.

The template is intentionally generic — it does not assume a specific tax-jurisdiction or currency formatting; consumers pass pre-formatted strings (date, currency symbol) and pre-computed numbers (subtotal, tax, total). The template focuses on layout, not arithmetic.

Features

  • Line-items table with description, quantity, unit price, total columns.
  • Subtotal + optional tax + total summary at right-align.
  • Optional paymentUrl renders a "Pay Now" CTA.
  • Currency symbol is configurable (currency defaults to "$").
  • Optional dueDate appears alongside the invoice date.

Usage: Basic

import { renderToHtml } from "@suaveplan/email-templates/renderer";
import { invoiceTemplate } from "@suaveplan/email-templates/templates";

renderToHtml(invoiceTemplate, {
  recipientName: "Jane",
  invoiceNumber: "INV-001",
  invoiceDate: "2026-01-15",
  items: [
    { description: "Pro plan – Jan 2026", quantity: 1, unitPrice: 29, total: 29 },
  ],
  subtotal: 29,
  total: 29,
});

Usage: Advanced

A multi-line invoice with tax, a due date, a payment CTA, and a non-USD currency:

import { renderToHtml } from "@suaveplan/email-templates/renderer";
import { invoiceTemplate } from "@suaveplan/email-templates/templates";

renderToHtml(invoiceTemplate, {
  recipientName: "Jane",
  invoiceNumber: "INV-001",
  invoiceDate: "2026-01-15",
  dueDate: "2026-01-31",
  currency: "€",
  items: [
    { description: "Pro plan – Jan 2026", quantity: 1, unitPrice: 29, total: 29 },
    { description: "Add-on: extra seat",  quantity: 2, unitPrice:  5, total: 10 },
  ],
  subtotal: 39,
  tax: 3.9,
  total: 42.9,
  paymentUrl: "https://billing.example.test/pay?invoice=INV-001",
});

API Reference

Symbol Kind Description
invoiceTemplate const EmailTemplate<InvoiceProps>.
InvoiceEmail function Component returning a VNode.
InvoiceProps type { recipientName, invoiceNumber, invoiceDate, dueDate?, items, subtotal, tax?, total, currency?, paymentUrl?, companyName? }
InvoiceLineItem type { description, quantity, unitPrice, total }.

Implementation Notes

Currency formatting uses Number.prototype.toFixed(2) — locale-agnostic two-decimal-place rendering. Consumers needing locale-aware grouping separators (e.g. 1,234.56 vs 1 234,56) should pre-format the strings upstream; the template intentionally does not depend on Intl.NumberFormat because email-template environments span Node, Bun, and browsers where the Intl data sets vary.

The line-items table renders a single <tbody> per call; the table header sits in its own <thead> so accessibility scanners report the correct table-with-headers structure even though most email clients ignore the distinction.