For the complete documentation index, see llms.txt. This page is also available as Markdown.

Certificates

This document covers printable documents in OpenCRVS — what they are, how they work end-to-end, and how to configure them.


What Are Certificates?

Certificates are printable PDF documents generated from event records. They are produced from SVG templates that are automatically populated with record data at print time.

Core provides the rendering pipeline, the PRINT_CERTIFICATE action type, and the data available to templates. Everything else — which templates exist, when they are shown, what form is shown during printing, and what flags are set — is configured in countryconfig.

Certificates are:

  • Data-driven — content is drawn from the live record, not typed manually.

  • Template-based — layout and design are controlled by SVG files defined in countryconfig.

  • Auditable — every print is recorded as a PRINT_CERTIFICATE action on the event, with who printed, when, where, and which template was used.

  • Workflow-aware — when and by whom documents can be printed is controlled via action conditionals and flags, all defined in countryconfig.


Document Types

From core's perspective, there is only one concept: a template. Core does not distinguish between a "certificate", "certified copy", or any other document type — those are naming conventions. Any number of templates can be registered per event. Each template is an SVG file with its own label, fee schedule, and display conditions.

The Farajaland countryconfig registers these templates for birth as an example of how templates can be structured:

Template ID
Label
When shown

birth-certificate

Birth Certificate

Only before any certificate has been printed (not(event.hasAction(PRINT_CERTIFICATE)))

birth-certified-certificate

Birth Certificate certified copy

Only after the original has been printed at least once

This sequencing — first issuance followed by re-issuance — is a countryconfig convention, not a core rule. You can register as many or as few templates as your country needs, with any conditions.


End-to-End Flow


Template Configuration

Templates are defined in countryconfig in the certificate handler:

The handler exports a certificateConfigs array. Core reads this endpoint to know which templates are available for each event. Each entry has this shape (ICertificateConfigData):

Key fields

id — The template's unique identifier. Referenced in withTemplate() conditionals and in ALPHA_PRINT_BUTTON field configs.

isDefault — If true, this template is pre-selected when the print form opens.

fee — Three-tier fee amounts. What counts as "on time", "late", or "delayed" is determined by the event's registration rules, not by this config.

svgUrl — URL path to the SVG template file served by countryconfig.

fonts — Font families to embed in the PDF. Each font family is an object with normal, bold, italics, bolditalics keys pointing to font file URLs.

conditionals — Controls when this template appears in the selection list. Uses the same condition API as the rest of the event config. If omitted, the template always appears.

Conditional examples


Template Files (SVG)

The SVG template files can live anywhere in countryconfig as long as the svgUrl in the config points to the correct URL. In Farajaland, they are placed in:

and the certificate handler serves them at /api/countryconfig/certificates/<filename> like this:

Templates are Handlebars SVG files — standard SVG syntax with {{ expressions }} for dynamic content. See Template Design for details.


Configuring the Print Action

PRINT_CERTIFICATE is a built-in action type. It is configured in the event's actions array:

printForm

The form shown to the user before the PDF is generated. Defined with defineActionForm(). The structure, pages, and fields are entirely up to the countryconfig. Core renders whatever pages are defined there.

conditionals

Controls when the Print action appears and whether it is enabled. Uses ConditionalType.SHOW and ConditionalType.ENABLE:

flags

Side-effects applied to the record when the print action completes. Flags are set or removed conditionally:

Flag IDs are defined entirely in countryconfig — core has no built-in certificate-specific flags.


The Print Form

The print form is defined using defineActionForm() and can have any number of pages. Core supports these page types that are particularly useful in print flows:

  • PageTypes.enum.FORM — a standard data-entry form page

  • PageTypes.enum.VERIFICATION — a page that shows record data alongside controls for the user to confirm or deny identity

The Farajaland countryconfig implements the print form as three pages as an example of one way to structure this:

Page 1 — Collector selection: A FORM page with a select field asking who is collecting the certificate. Farajaland uses values like INFORMANT, OTHER, and PRINT_IN_ADVANCE, with additional fields appearing conditionally based on the selection.

Page 2 — Identity verification: A VERIFICATION page (shown conditionally based on the selection in page 1) that renders key record fields from $declaration alongside a confirm/deny action. This lets the registrar cross-reference the collector against the record without leaving the flow.

Page 3 — Payment: A FORM page using FieldType.DATA to display the fee and service. The values can be hardcoded or derived conditionally.

Your print form does not need to follow this structure. It can have more or fewer pages, different fields, or no collector step at all.

Accessing print form values in the template

All annotation fields captured in the print form are accessible in the SVG template:


Business Rules and Flags

Flags are boolean markers on a record that any action can set or remove. They are defined entirely in countryconfig — core provides the flag mechanism but has no certificate-specific built-in flags.

Controlling access with conditionals

Sequencing templates

To enforce that one template must be printed before another appears, use withTemplate().minCount() in the template config:

This is how the Farajaland countryconfig ensures the certified copy only becomes available after the original certificate has been printed.

Tracking print count

Core automatically tracks how many times a given template has been printed in $metadata.copiesPrintedForTemplate. Use it in your template to mark re-prints:


Template Design

Certificate templates are SVG files with Handlebars expressions. The SVG defines the visual layout; Handlebars expressions pull in record data at print time. This is implemented in core (compileSvg in pdfUtils.ts).

How rendering works

  1. The SVG file is fetched from the svgUrl in the template config.

  2. Handlebars compiles the SVG string, resolving all {{...}} expressions against the record's data.

  3. The compiled SVG is converted to a PDF via pdfmake.

  4. The PDF is downloaded or sent to the printer.

What data is available

Four top-level variables are available in every template — these are provided by core:

Variable
Contains

$declaration

All form field values from the declaration, pre-resolved into human-readable strings

$metadata

Event lifecycle data — registration number, dates, users, offices, legal statuses

$review

true when previewing before print, false when actually printing

$references

Raw location and user maps (rarely used directly)

Reading values

Use $lookup to navigate into any variable:

Built-in helpers

These are all registered by core in pdfUtils.ts:

Helper
Purpose

$lookup obj "path"

Navigate into any data object by dot-path

$intl "key.part1" dynamicValue

Translate an i18n key built from joined parts

$intlWithParams "id" "paramName" value

Translate with interpolated values

$join ", " val1 val2 val3

Join values, filtering out empty ones

$or val1 val2

First truthy value

{{#ifCond v1 "===" v2}} ... {{/ifCond}}

Conditional blocks with comparison operators

$action "TYPE"

Most recent action of a given type

$actions "TYPE"

All actions of a given type as an array

$json value

JSON string representation (debug only)

Registrar signature

The registrar's signature is stored on the REGISTER action and accessible via:

Review mode

$review is true during the preview step and false when actually printing. Use it to show draft watermarks or hide print-only elements:

Multi-page templates

Core supports multi-page certificates via the data-page attribute on SVG groups. See certificate-multipage.md for the full guide.

Custom helpers

Countryconfig can define additional Handlebars helpers in:

Core compiles this file to JavaScript, serves it at /handlebars.js, and loads it before rendering any template. See certificate-custom-helpers.md for the full guide.


Further Reading

Topic
Document

All template variables and built-in helpers (detailed reference)

Writing custom Handlebars helpers

Multi-page certificate templates

Last updated