Brands and variables
Brands hold the visual identity that templates reuse (logo, colours, footer text); variables hold the dynamic content that renders per message (user name, order id, amount). Both are dashboard-managed and feed into the same template editor.TL;DR
- Brand is a top-level dashboard concept (
/org/:org/app/brand). One per organisation, sometimes per environment. - Organisation variables are global — defined once, reusable across every campaign.
- Environment variables (Notifizz’s, distinct from your runtime env vars) are scoped per environment, edited inline from the campaign flow.
- Variables are referenced as
{{var:<id>}}tokens; the catalog resolves names at render time.
Brand
A brand groups visual identity tokens that every campaign template inherits:| Token | Example |
|---|---|
| Primary colour | #C923A6 |
| Secondary colour | #1A1A1A |
| Logo (light) | https://cdn.example.com/logo-light.svg |
| Logo (dark) | https://cdn.example.com/logo-dark.svg |
| Default font | Inter, system-ui, sans-serif |
| Footer text | © Example Corp — Privacy · Terms · Unsubscribe |
| Sender name | Example Notifications |
Variables — two scopes
The variable system supports two scopes:Organisation variables
Defined once at the organisation level, reusable across every campaign. Edited from organisation settings. Common patterns:| Variable | Why org-wide |
|---|---|
support_email | Same support address across every notification. |
app_name | Branded name used in subject lines. |
cta_url_base | Common URL prefix for in-app CTAs. |
unsubscribe_url_template | Same unsubscribe pattern across marketing campaigns. |
{{var:org.support_email}} (or via the editor’s variable picker). Resolution happens at message render time.
Environment variables (Notifizz’s)
Scoped per environment, edited inline from the campaign flow. Useful for environment-specific values that shouldn’t pollute the organisation-wide list:| Variable | Why per-env |
|---|---|
dashboard_url | dev.example.com vs app.example.com |
support_phone | Test number on dev, real number on prod |
region_specific_legal_text | EU vs US compliance footer |
{{var:env.dashboard_url}}. The render-time resolution picks the value for the environment where the message is being delivered.
Don’t confuse Notifizz’s “environment variables” (template tokens scoped to a Notifizz environment) with your application’s runtime env vars (
process.env.X). They live in different worlds — Notifizz variables don’t interpolate from your shell, and your shell vars never leak into Notifizz templates.Variable resolution
At message creation time:Extract variable IDs from the template
The system walks the rendered config tree and collects every
{{var:<id>}} token.Build the variable catalog
For each id, look up the variable definition (org or env scope). Bundle into a small catalog object — only the variables actually used in this template, not the whole org’s catalog.
Name collisions
Org and env scopes can both define a variable with the same name. Resolution rules:- IDs are serialised with their scope prefix (
org.foovsenv.foo), so the variable picker never produces a collision. - The editor warns if a template references a variable id that doesn’t exist in either scope.
{{var:env.missing}}) — easy to spot and fix.
Usage count
Each variable tracks how many templates reference it. The count auto-increments when a template is saved with the variable referenced and decrements when a template removes the reference. Use it to find dead variables (usageCount === 0) before retiring.
The diff is best-effort — if the count gets out of sync (rare), the dashboard exposes a “recompute usage counts” maintenance action.
Recipient fields vs variables
Don’t confuse:- Recipient custom fields (
{{ recipient.displayName }}) — produced by the orchestrator, vary per recipient within a single workflow instance. - Variables (
{{var:org.app_name}}) — defined in the dashboard, same value for every recipient of a given template.
Hi {{ recipient.displayName }}, your {{ var:org.app_name }} order shipped resolves the displayName per recipient and the app_name from the org variable catalog.
FAQ
Variable resolves to empty string — why?
Variable resolves to empty string — why?
Three causes: (1) the variable is defined but its value is empty (check the dashboard); (2) the template references a variable id that doesn’t exist (the rendered output shows the literal
{{var:...}} token in that case); (3) the variable was renamed after the template was saved — re-save the template to pick up the new id.Variable scoped to one campaign?
Variable scoped to one campaign?
Not directly — variables are org-wide or env-wide. For per-campaign data, use recipient custom fields (set in the orchestrator) or event properties (in
{{ event.foo }} references). If you find yourself wanting many per-campaign variables, the right layer is probably the orchestrator’s recipient list.Preview a rendered notification with sample variables?
Preview a rendered notification with sample variables?
The dashboard’s template editor exposes a preview pane with editable sample values for every referenced variable + a sample recipient object. Render the preview to see the rendered output before promoting to
Live.Name collision — org variable and env variable with the same name. Who wins?
Name collision — org variable and env variable with the same name. Who wins?
Neither — they have distinct serialised IDs (
org.foo vs env.foo). The editor’s variable picker never produces an ambiguous reference. If you’re hand-editing the template HTML and use {{var:foo}} without scope, the editor will flag it as invalid.Store secrets as variables?
Store secrets as variables?
No. Variables are part of the message snapshot — anyone with access to delivery history can read them. Use them for non-sensitive values (URLs, copy, branding); never API keys or PII beyond what your privacy policy already covers.
What happens to past messages when I rename a variable?
What happens to past messages when I rename a variable?
Nothing — the variable name and value were snapshot on the message at creation time. Past messages render the same way they always did. Future messages pick up the new variable name and value.
See also
Channels (detail)
Where templates dispatch to.
Recipients
Recipient custom fields vs variables.
Link routes
Variables inside tracked URLs.
Activity log
Audit trail of variable edits.