Email templates in self-hosted Ory Kratos
Configuration
In self-hosted Ory Kratos instances, you can add custom templates from http://, file://, and base64:// URIs. The plaintext
and html fields are mandatory when defining the body key. All other keys are optional. If the system can't use the custom
template, it doesn't fall back. If you don't configure a template, the system uses the matching file in template_override_path
(if specified) or the built-in template.
The template_override_path directory and any file:// template URIs are automatically allow-listed by the
Landlock filesystem sandbox — Kratos walks the loaded config at startup and
allow-lists every file:// URI it finds, regardless of where on disk the template lives. No security.landlock.allowed_paths
entry is required.
courier:
template_override_path: /conf/courier-template
# ...
templates:
verification:
valid:
email:
body:
html: https://some-remote-resource/gotmpl
plaintext: base64://SGV5IHlvdSBkZWNvZGVkIG1lIDop
# optionally, define the subject
subject: file://some-file/subject.gotmpl
When self-hosting Ory Kratos, the system expects the templates at these paths:
<kratos-root>/<template-root>/recovery/valid<kratos-root>/<template-root>/recovery/invalid<kratos-root>/<template-root>/verification/valid<kratos-root>/<template-root>/verification/invalid
Read this document to learn more about the email courier and the specifics of using templates in self-hosted Ory Kratos instances.
Template language
By default, Ory Kratos Identities applies the same
template language rules and limits in Ory Enterprise License (Ory
OEL) and Ory Open Source (Ory OSS) as in Ory Network. They cover templates set in courier.templates, the files in
template_override_path, and the built-in templates. Override files that match one template's pattern, such as the
email.body*.gotmpl files for translated templates, count as one template.
If your templates need the unrestricted template language, set courier.legacy_unrestricted_templates to true. This turns off
both the rules and the limits:
courier:
legacy_unrestricted_templates: true
Translated templates (I18n)
To create internationalized templates, you can either use in-line template definitions, as described
here, or as in this example, use separate template files.
The following example defines the message body for recovery emails. It assumes that there is a lang attribute defined in the
identity traits that contains the preferred language of the user.
{{- if eq .Identity.traits.language "de" -}}
{{ template "email.body.de.gotmpl" . }}
{{- else -}}
{{ template "email.body.en.gotmpl" . }}
{{- end -}}
{{ .RecoveryCode }}
Hallo {{ upper .Identity.traits.firstName }},
Um Ihr Konto wiederherzustellen, geben Sie bitte den folgenden Code ein:
Hello {{ upper .Identity.traits.firstName }},
to recover your account, please enter the following code:
The i18n template is nested in the root email.body.gotmpl template. The sub-templates must conform to the email.body* pattern.
The identity of the user is available in all templates.
