Skip to content

API Reference

Aurghyadip edited this page Aug 3, 2026 · 1 revision

API Reference

Exhaustive API reference for all public exported symbols in typst-mailmerge.


πŸ“‘ Core Functions

#mail-merge(...)

Main engine for multi-page or single-page document merges (letters, certificates, invoices).

#mail-merge(
  data,
  template,
  filter: none,
  sort-by: none,
  reverse: false,
  start: 1,
  limit: none,
  pagebreak: true,
  reset-page-counter: false,
  trim: true,
  default-value: "",
  on-empty: [No matching records found.]
)
Parameter Type Default Description
data str | array Required Path to CSV, pre-loaded csv(...), array of dicts, or 2D row arrays.
template function Required Content closure record => content.
filter none | function | dict none Predicate closure r => bool or dict (Key: Value).
sort-by none | str | function none Field name string or key extractor closure r => key.
reverse bool false Reverses sorted order when true.
start int 1 1-based start record index for pagination.
limit none | int none Maximum number of records to process.
pagebreak bool true Inserts #pagebreak() between rendered records.
reset-page-counter bool false Executes counter(page).update(1) for each recipient document.
trim bool true Trims leading/trailing whitespace from string fields.
default-value str "" Fallback value for missing or empty CSV fields.
on-empty content [...] Content displayed if zero records match.

#mail-merge-labels(...)

Grid engine for multi-column sticker sheets, labels, and badges.

#mail-merge-labels(
  data,
  template,
  preset: none,
  columns: none,
  rows: none,
  width: none,
  height: none,
  column-gutter: none,
  row-gutter: none,
  page-margin: none,
  paper: none,
  cell-padding: none,
  show-cut-lines: false,
  fill: none,
  filter: none,
  sort-by: none,
  reverse: false,
  start: 1,
  limit: none,
  trim: true,
  default-value: "",
  on-empty: [No matching records found.]
)
Parameter Type Default Description
preset dictionary none Predefined layout dictionary from presets.*.
columns int 3 Number of columns per grid sheet.
rows int 8 Number of rows per grid sheet.
width length | relative | 1fr 1fr Cell width.
height length | relative | 1fr 1fr Cell height.
column-gutter length 0pt Space between grid columns.
row-gutter length 0pt Space between grid rows.
page-margin none | length | dict none Page margins.
paper none | str none Paper size (e.g. "us-letter", "a4").
cell-padding length | dict 4pt Inset padding inside label boxes.
show-cut-lines bool | stroke false Visual guidelines stroke around cells.
fill none | color | function none Cell background fill or closure record => color.

πŸ”§ Field Utility Functions

#field(record, key, fmt: none, default: "")

Retrieves a field with normalized key search ("First Name", "first_name", "First-Name") or candidate keys array.

#fmt-field(record, key, fmt: none, default: "")

Alias for field(record, key, fmt: fmt, default: default).

#bind-field(record)

Binds record to field(), returning function (key, fmt: none, default: "") => val.

#join-fields(record, keys, separator: ", ", default: "")

Joins non-empty values from keys array into a single string/content with separator.

#if-field(record, key, then-content, else-content: [])

Renders then-content (or then-content(val)) if field is non-empty, otherwise else-content.

#is-empty(record, key) / #is-non-empty(record, key)

Boolean predicate helpers for field emptiness.

Record Index & Metadata Helpers

  • record-index(record) β€” 1-based index of current record.
  • record-total(record) β€” Total count of records in current merge.
  • is-first-record(record) β€” True for the first record.
  • is-last-record(record) β€” True for the last record.

πŸ“Š Inspection Helpers

#mail-merge-stats(data, filter: none, trim: true, default-value: "")

Returns (total-records: int, fields: array, sample-record: dict).

#mail-merge-preview(data, template, limit: 3, ..options)

Renders rapid draft preview limited to limit records.

Clone this wiki locally