Skip to content

Writing Templates

A prompt template is a string. At render time, Logfire walks that string with a Handlebars engine and substitutes in the current variables.

If you already know Handlebars, the short version is: Logfire uses the standard Handlebars.js helper set, with no custom helpers enabled by default.

If you do not, keep reading. The surface you need is small.

Simple variables

Use double braces to insert a value:

Hi {{customer_name}}, thanks for contacting us about {{topic}}.

If the scenario’s variables panel has customer_name = Taylor and topic = your recent order, the template renders as:

Hi Taylor, thanks for contacting us about your recent order.

Variable names in the scenario panel can use plain identifiers (customer_name, topic) or dotted keys (customer.name, customer.tier). Dotted keys are unpacked into a nested object, so customer.name = Taylor and customer.tier = gold both become reachable inside the template as {{customer.name}} and {{customer.tier}}.

Hi {{customer.name}} ({{customer.tier}} tier), ...

Conditionals and loops

The standard Handlebars block helpers work:

{{#if customer.vip}}
This customer is VIP — escalate immediately.
{{/if}}

Reusable fragments

Use @{variable_name}@ to compose managed-variable values into a prompt before the prompt’s {{...}} placeholders are rendered.

You are the support assistant for @{support_brand_profile.product}@.

@{support_safety_rules}@

Reply to {{customer_name}} on the {{tier}} plan.

Composition is useful when a fragment should have its own version history, targeting, or owner. A prompt can reference regular managed variables such as @{support_safety_rules}@ and other prompts through their backing variable names, such as @{prompt__support_style}@.

For a full example, see the Prompt composition walkthrough.

Scenario-specific rendering

The prompt editor reuses the same template engine for saved test scenarios, including scenario messages, tool-call arguments, and tool-return content.

Two scenario-only details are documented separately because they are part of testing a prompt rather than authoring the prompt template itself:

  • the @{prompt}@ alias, which injects the rendered prompt into a scenario message,
  • recursive rendering inside tool-call args and tool-return content.

See Test Prompts for the workflow and Template reference for the exact rules.

What is not supported

Only the standard Handlebars.js helper set is enabled on both the editor and the server. In particular, the following are not available:

  • Custom helpers — for example, {{uppercase name}}, {{json obj}}, {{eq a b}}. (The server’s Handlebars engine can be extended with a set of 16 extra helpers, but the prompt-rendering pipeline explicitly disables them to keep editor preview and server execution identical.)
  • Partials{{> partialName}} is not used by the feature.
  • Inline helpers — Handlebars’ {{#*inline "name"}} block is not used.

If you need transformation logic that is not expressible in plain Handlebars, do that work in your application code against the rendered template, not inside the template itself.

Rendering from your application

The Logfire SDK can render prompt templates for you with logfire.template_var(). If you fetch a prompt with logfire.var() instead, .get() returns the prompt template after @{...}@ composition has been expanded, and your application renders the remaining {{...}} placeholders before passing the result to your model client.

If you want to keep manual rendering simple, prefer flat variables such as {{customer_name}}. If you want to use dotted paths or block helpers, make sure your application uses a renderer that supports the same Handlebars features described here.

See Use Prompts in Your Application for the current integration workflow.

See the full grammar and its error behavior in the Template reference.