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_CERTIFICATEaction 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:
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
printFormThe 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
conditionalsControls when the Print action appears and whether it is enabled. Uses ConditionalType.SHOW and ConditionalType.ENABLE:
flags
flagsSide-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 pagePageTypes.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
The SVG file is fetched from the
svgUrlin the template config.Handlebars compiles the SVG string, resolving all
{{...}}expressions against the record's data.The compiled SVG is converted to a PDF via pdfmake.
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:
$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:
$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
All template variables and built-in helpers (detailed reference)
Writing custom Handlebars helpers
Multi-page certificate templates
Last updated