Skip to Content
DocumentationBuildPatternsTemplate Expressions

Template Expressions

Use Handlebars templates to render dynamic text content in workflows. Call this.render() from any BaseWorkflow to interpolate state values, format prompts, and generate dynamic output.

Setup

import { BaseWorkflow, Transition, Workflow } from '@loopstack/common'; @Workflow({}) export class MyWorkflow extends BaseWorkflow { // this.render() is available from BaseWorkflow — no injection needed }

Usage

const rendered = this.render(__dirname + '/templates/prompt.md', { subject: args.subject, items: state.items, });

Template file (templates/prompt.md):

Write a haiku about {{subject}}. {{#each items}} - {{this.name}} {{/each}}

Passing Data

Pass any data as the second argument to this.render():

// Workflow args (from ctx parameter) const args = ctx.args as { subject: string }; this.render(templatePath, { subject: args.subject }); // Workflow state (from state parameter) this.render(templatePath, { items: state.items, count: state.counter }); // Mixed data this.render(templatePath, { prompt: args.prompt, history: state.conversationHistory, timestamp: new Date().toISOString(), });

Handlebars Syntax

Variables

Hello {{name}} Nested: {{user.profile.email}} Array element: {{items.[0]}}

Conditionals

{{#if isActive}}Welcome back!{{else}}Please log in{{/if}} {{#unless isBlocked}}Access granted{{/unless}}

Iteration

{{#each items}} - {{this.name}}: {{this.value}} {{else}} No items found. {{/each}}

Context Scoping

{{#with user}}{{name}} ({{email}}){{/with}}

Multi-line Template Example

# Events This Week {{#each events}} - **{{this.summary}}**: {{this.start}} – {{this.end}} {{/each}} {{#unless events}} No events found. {{/unless}}

When to Use Templates

ScenarioApproach
LLM prompts with variablesthis.render(templatePath, data)
Simple string interpolationTemplate literals in TypeScript
Complex multi-line contentHandlebars template file
Prompts with iteration/conditionalsHandlebars with #each, #if

YAML UI Config

YAML widget configuration uses transition values that reference method names and enabledWhen for conditional visibility. These are not template expressions — they are static configuration:

ui: widgets: - widget: prompt-input enabledWhen: [waiting_for_user] options: transition: userMessage

Registry References

Last updated on