Skip to content

feature: Support Template Strings in Nested Object/Array Fields (Flow Editor) #7257

@androidfans

Description

@androidfans

Support Template Strings in Nested Object/Array Fields (Flow Editor)

🐛 Problem Description

In Windmill's Flow editor, only top-level string parameters support template strings (e.g., ${results.previous_step.value}). When a script parameter is an
object or array with nested fields, the entire structure must be edited in JavaScript Expression mode, losing the visual editing experience.

This makes it cumbersome to work with common patterns like HTTP headers, where most fields are static but one or two need dynamic values.

📸 Current Behavior

Given this script:

interface Header {
    key: string;
    value: string;
}

export async function main(
    value: string,        // ✅ Has template string support
    header: Header,       // ❌ No template support for nested fields
    headers: Header[],    // ❌ Must edit entire array as JS code
) {
    return
}

What happens:

  1. The value parameter shows a text input with ${} button - works great!
  2. The header parameter shows form fields for key and value, but:
    - No ${} button on the nested value field
    - To use ${results.b.api_key}, must switch entire object to JavaScript mode
  3. The headers array is even worse:
    - Can add items visually, but no template strings in fields
    - To use dynamic values, must switch to JavaScript mode and write:
([
  { key: "X-Engine", value: "direct" },
  { key: "X-Locale", value: "zh-CN" },
  { key: "Authorization", value: `Bearer ${results.b.api_key}` }  // Only this field needs to be dynamic!
])

🎯 Expected Behavior

Every visible input field in the Flow editor should support template strings, similar to how n8n handles expressions:

  1. Nested object fields should have their own ${} toggle button
  2. Array items' fields should each support template strings independently
  3. UI should stay visual - no sudden jump to JavaScript editor when using ${...}
  4. Simple mixed scenarios should work: some fields static, some dynamic, without writing code

💡 Desired User Experience

headers (array):
Item 1:
key: [X-Engine ]
value: [direct ]

Item 2:
  key:   [Authorization            ]
  value: [Bearer ${results.b.api_key}]  ← Has ${} button, can use template!

[+ Add item]

User should be able to:

  • Type template strings directly into any nested field
  • Mix static and dynamic values within same object/array
  • Never need to write JavaScript code for simple cases
  • See the ${} button on every string field

🔧 Technical Context

Currently, InputTransformForm.svelte handles flow inputs:

  • String fields: Uses TemplateEditor → supports ${...} syntax ✅
  • Object/Array fields: Uses ArgInput → calls SchemaForm → renders nested fields with plain ArgInput (no template support) ❌

The issue is that nested rendering doesn't go through InputTransformForm recursively, so nested fields don't get template string capabilities.

🌟 Comparison with Other Tools

n8n: Every input field across all node parameters supports {{ expression }} syntax, regardless of nesting depth.

Windmill (current): Only top-level string fields support ${...} template strings.

📦 Use Cases

  1. HTTP Headers: Most headers are static (Content-Type, Accept), but Authorization header needs dynamic token from previous step
  2. API Request Bodies: Nested JSON where only certain fields are dynamic
  3. Database Records: Batch inserts where some fields come from flow results, others are constants
  4. Configuration Objects: Complex configs where only credentials/endpoints are dynamic

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions