Email Templates Reference
This guide documents the placeholders (merge fields) you can use when customizing four transactional emails. It is written for people editing the email content — not for developers.
| Template | When it is sent | Sent to |
|---|---|---|
User registration (user_register_success) | After a new customer account is created | The customer |
Password reset (user_password_reset) | When a customer requests a password reset link | The customer |
Quote request — customer (quote_request_customer) | When a customer submits a quote request | The customer |
Quote request — admin (quote_request_admin) | When a customer submits a quote request | The shop's contact address |
How placeholders work
Each template supports merge fields — tokens in the content that are replaced with real values when the email is sent. All templates use the same token style:
- Dotted style:
{{ .firstName }},{{ .quoteId }},{{ .shop.name }}.
The tables below show the exact token for each field. If a field is left out or has no value, the token is simply replaced with an empty string.
Shop fields (always available)
These describe the shop and can be used in any template:
| Field | Description | Example |
|---|---|---|
{{ .shop.name }} | Shop name | Acme Store |
{{ .shop.url }} | Shop website address | https://shop.example.com |
{{ .shop.logo }} | Shop logo image URL | https://shop.example.com/logo.png |
{{ .shop.contactEmail }} | Shop contact email | [email protected] |
Only these shop fields are exposed — the underlying tenant configuration (which also holds secrets like mail passwords and API keys) is not available to templates.
Legacy alias: older templates may use
{{ .configuration.shop_name }}/.page_url/.shop_logo. Those still work (a filtered, non-sensitive subset), but new templates should use{{ .shop.* }}.
Languages & versioning
- One file per language. Each template is stored per language (
en,lt, …); the version for the recipient's language is used. Editing the content for one language does not affect the others. - Editing a template in the admin marks it customized — the system will never overwrite your changes when shipped defaults are updated.
- Shipped updates to the default content are re-applied only to templates you have not customized (tracked by a template version number). Your edits always win.
Related — but separate: order, quote, and proforma PDF documents are produced by the business/ERP system, not by these email templates. Those use a versioned render schema (
orderDocument.v1) with a much larger field set. See the ERP guide "Order, Quote, And Proforma PDF Templates" for those merge fields.
1. User registration — user_register_success
A welcome email sent to a customer after their account is created.
Subject: [{{ .shop.name }}] Welcome joining {{ .shop.name }} community
Available fields
| Field | Description | Example |
|---|---|---|
{{ .firstName }} | Customer first name | John |
{{ .lastName }} | Customer last name | Smith |
{{ .email }} | Customer email address | [email protected] |
{{ .shop.name }} | Shop name | Acme Store |
{{ .shop.url }} | Shop website address | https://shop.example.com |
{{ .shop.logo }} | Shop logo image URL | https://shop.example.com/logo.png |
Rendered subject: [Acme Store] Welcome joining Acme Store community
Example
<img src="{{ .shop.logo }}" alt="{{ .shop.name }}" style="max-height:60px">
<h1>Hello, {{ .firstName }} {{ .lastName }}!</h1>
<p>Thank you for creating an account at {{ .shop.name }}.</p>
<p>Your login email: {{ .email }}</p>
<a href="{{ .shop.url }}">Visit the shop</a>Renders for John Smith at Acme Store:
[Acme Store logo]Hello, John Smith! Thank you for creating an account at Acme Store. Your login email: [email protected]Visit the shop
2. Password reset — user_password_reset
Sent when a customer requests a link to reset their password. The reset link is valid for a limited time after it is sent.
Subject: [{{ .shop.name }}] Password reset
Available fields
| Field | Description | Example |
|---|---|---|
{{ .resetUrl }} | Full password reset link | https://shop.example.com/reset-password?code=AbC123... |
{{ .shop.name }} | Shop name | Acme Store |
{{ .shop.url }} | Shop website address | https://shop.example.com |
{{ .shop.logo }} | Shop logo image URL | https://shop.example.com/logo.png |
Rendered subject: [Acme Store] Password reset
Example
<img src="{{ .shop.logo }}" alt="{{ .shop.name }}" style="max-height:60px">
<h1>Password reset</h1>
<p>We received a request to reset your {{ .shop.name }} password.</p>
<a href="{{ .resetUrl }}">Reset your password</a>
<p>If you didn't request this, you can ignore this email.</p>Renders:
[Acme Store logo]Password reset We received a request to reset your Acme Store password. Reset your password If you didn't request this, you can ignore this email.
3. Quote request — customer — quote_request_customer
Confirmation to the customer that their quote request was received.
Subject: [{{ .shop.name }}] Quote request no. {{ .quoteId }} received
4. Quote request — admin — quote_request_admin
Notification to the shop that a new quote request arrived. It uses the same fields as the customer version, and is sent to the shop's contact email address.
Subject: [{{ .shop.name }}] New quote request no. {{ .quoteId }}
Available fields (both quote templates)
| Field | Description | Example |
|---|---|---|
{{ .quoteId }} | Quote request number | 1042 |
{{ .token }} | Unique quote reference used in links | q_9f3a7c... |
{{ .title }} | Quote title | Office refit |
{{ .requestMessage }} | Message the customer submitted | Please quote for 10 desks |
{{ .currency }} | Currency code | USD |
Requester — inside {{ with .customer }}
Who submitted the request. Most useful in the admin template (so staff can see who to reply to).
| Field | Description | Example |
|---|---|---|
{{ .customer.name }} | Requester name | John Smith |
{{ .customer.email }} | Requester email | [email protected] |
{{ .customer.phone }} | Requester phone (business requests) | +1 555 010 1234 |
{{ .customer.company }} | Company name (business requests) | Acme Corp |
{{ .customer.companyCode }} | Company registration code | 123456789 |
{{ .customer.vatCode }} | VAT code | US123456789 |
Cart-based requests populate name and email only; phone/company fields are filled for standalone business requests. Empty fields render blank.
Quote link: {{ .shop.url }}/quotes/{{ .token }} → https://shop.example.com/quotes/q_9f3a7c...
Line items — inside {{ range .lineItems }}
Each requested product appears as a line item with these fields:
| Field | Description | Example |
|---|---|---|
{{ .productName }} | Product name | Desk 120cm |
{{ .description }} | Product description | Adjustable-height desk |
{{ .articule }} | Product code / SKU | DSK-120 |
{{ .quantity }} | Quantity requested | 10 |
{{ .measurementUnit }} | Unit of measure | pcs |
{{ formatPrice .priceInclTax }} | Unit price incl. tax | 149.00 |
{{ formatPrice .total }} | Line total, excl. tax | 1400.00 |
{{ formatPrice .totalInclTax }} | Line total, incl. tax | 1490.00 |
{{ .vatPercentage }} | VAT rate (%) | 21 |
{{ formatPrice .discountPerUnit }} | Discount per unit | 10.00 |
{{ formatPrice .totalDiscount }} | Line discount total | 100.00 |
{{ .currency }} | Currency code | USD |
{{ range .charges }} | Line-level charges — each has .chargeName, .chargeAmount, .totalAmount | surcharges/tariffs |
Unit vs. line total:
priceInclTaxis the price of one unit;totalInclTaxis the whole line (quantity × price, less discounts). A quote table usually shows both.
Product catalog details — {{ .product }}
Each line also carries the full product record under {{ .product }} (the same object the order confirmation uses; also available as {{ .productInfo }}). Commonly useful fields:
| Field | Description | Example |
|---|---|---|
{{ .product.brand }} | Brand name (also {{ .product.brandInfo.name }}) | Acme |
{{ .product.description }} | Catalog description | Adjustable-height desk |
{{ .product.image }} | Product image URL (also imageSmall, images) | https://shop.example.com/img/desk.jpg |
{{ .product.supplierCode1 }} | Supplier code (also supplierCode2, supplierCode3) | SUP-4471 |
Optional fields: some fields (e.g. the supplier codes) are only present when the product has them — guard with a conditional, otherwise a missing value shows as
<no value>:{{ if .product.supplierCode1 }}Supplier: {{ .product.supplierCode1 }}{{ end }}
{{ .product }}carries many more fields (weight, categories, price tiers…). The line's ownproductName,articule,quantityand prices live directly on the line (above), not under.product.
Totals — inside {{ with .totals }}
| Field | Description | Example |
|---|---|---|
{{ formatPrice .totalInclTax }} | Order total incl. tax | 1490.00 |
{{ formatPrice .total }} | Order total | 1490.00 |
{{ formatPrice .totalExclTax }} | Total excl. tax | 1400.00 |
{{ formatPrice .totalTax }} | Total tax | 90.00 |
{{ formatPrice .totalShippingInclTax }} | Shipping total incl. tax | 0.00 |
{{ formatPrice .totalDiscountInclTax }} | Discount total incl. tax | 0.00 |
formatPriceformats a number with two decimals (e.g.149.00). Use it around any price field.
Example values
quoteId = 1042
token = q_9f3a7c...
title = Office refit
requestMessage = Please quote for 10 desks
currency = USD
lineItems:
- productName = Desk 120cm
articule = DSK-120
priceInclTax = 149.00
currency = USD
quantity = 10
measurementUnit = pcs
totals:
total = 1490.00
totalInclTax = 1490.00
totalExclTax = 1400.00
totalTax = 90.00Rendered subject (customer): [Acme Store] Quote request no. 1042 received Rendered subject (admin): [Acme Store] New quote request no. 1042
Example (customer)
This shows the two things people most often get wrong — a loop over line items and a conditional block:
<h1>Quote request no. {{ .quoteId }} received</h1>
<p>Thank you — we received your request and will get back to you shortly.</p>
{{ if .requestMessage }}
<p><strong>Your message:</strong> {{ .requestMessage }}</p>
{{ end }}
<table>
<tr><th>Product</th><th>Qty</th><th>Price</th></tr>
{{ range .lineItems }}
<tr>
<td>{{ .productName }}</td>
<td>{{ .quantity }} {{ .measurementUnit }}</td>
<td>{{ formatPrice .priceInclTax }} {{ .currency }}</td>
</tr>
{{ end }}
</table>
{{ with .totals }}
<p><strong>Total: {{ formatPrice .totalInclTax }} {{ $.currency }}</strong></p>
{{ end }}
<a href="{{ .shop.url }}/quotes/{{ .token }}">View your quote</a>Renders (quote #1042 for 10 desks):
Quote request no. 1042 received Thank you — we received your request and will get back to you shortly. Your message: Please quote for 10 desks
Product Qty Price Desk 120cm 10 pcs 149.00 USD Total: 1490.00 USDView your quote
Note on
{{ with .totals }}: inside arangeorwithblock,.refers to the current item — use$.currency(with the$) to reach a top-level field from inside the block.
Example (admin)
The admin template uses the same fields — only the wording differs (it's a notification, not a confirmation), and it typically shows who the request is from:
<h1>New quote request no. {{ .quoteId }}</h1>
{{ with .customer }}
<p>From: {{ .name }} ({{ .email }}){{ if .company }} — {{ .company }}{{ end }}</p>
{{ if .phone }}<p>Phone: {{ .phone }}</p>{{ end }}
{{ end }}Renders:
New quote request no. 1042 From: John Smith ([email protected]) — Acme Corp Phone: +1 555 010 1234
Quick reference
| Template | Languages | Sent to |
|---|---|---|
user_register_success | en, lt | The customer |
user_password_reset | en, lt | The customer |
quote_request_customer | en, lt | The customer |
quote_request_admin | en, lt | The shop contact address |
All templates use the dotted {{ .field }} token style.
Formatting helpers
| Helper | Purpose | Example output |
|---|---|---|
formatPrice | Format a number with 2 decimals | 149.00 |
formatDate | Format a date as YYYY-MM-DD | 2026-07-15 |
formatDateUS | Format a date as MM/DD/YYYY | 07/15/2026 |
formatDatetimeUS / formatDateTimeUS | Format date & time, US style | 07/15/2026 02:30 PM |
nl2br | Convert line breaks to <br> | multi-line text |
Use {{ formatDateUS .someDate }} for US-style dates. formatPrice is mainly used by the quote templates (which carry prices and dates).