Skip to main content

Overview

The JavaScript Code node executes custom JavaScript code within your workflow. It provides full access to the workflow context, allowing you to manipulate data, implement complex logic, interact with the page, and integrate with external systems.
This node executes arbitrary JavaScript code. In production environments, ensure proper security controls and code review processes are in place.

Configuration

code
string
required
JavaScript code to execute. The code runs in an async function context, so you can use await for asynchronous operations.

Available Context

The context object provides access to workflow data and functions:

Context Methods

context.getData(key)
function
Retrieve data from the workflow context.
const users = context.getData('users');
const apiResponse = context.getData('apiResponse');
context.setData(key, value)
function
Store data in the workflow context.
context.setData('processedUsers', filteredUsers);
context.setData('shouldContinue', true);
context.getVariable(key)
function
Get a workflow variable (similar to getData).
const itemId = context.getVariable('currentItemId');
context.setVariable(key, value)
function
Set a workflow variable.
context.setVariable('processCount', count);
context.getAllData()
function
Get all data from the workflow context.
const allData = context.getAllData();
console.log('Context data:', allData);
context.getAllVariables()
function
Get all workflow variables.
const allVars = context.getAllVariables();

Page Access

context.page
Page
Access the Playwright Page object for direct browser interaction.
const title = await context.page.title();
const url = context.page.url();

Examples

Data Manipulation

{
  "type": "javascriptCode",
  "data": {
    "code": "const products = context.getData('products'); const expensive = products.filter(p => parseFloat(p.price.replace('$', '')) > 100); context.setData('expensiveProducts', expensive); console.log(`Found ${expensive.length} expensive products`);"
  }
}

Conditional Logic

{
  "type": "javascriptCode",
  "data": {
    "code": "const count = context.getData('itemCount'); if (count > 10) { context.setData('shouldPaginate', true); console.log('Pagination needed'); } else { context.setData('shouldPaginate', false); }"
  }
}

String Operations

{
  "type": "javascriptCode",
  "data": {
    "code": "const text = context.getData('rawText'); const formatted = text.trim().toLowerCase().replace(/\\s+/g, '-'); context.setData('formattedText', formatted);"
  }
}

Date and Time

{
  "type": "javascriptCode",
  "data": {
    "code": "const now = new Date(); const timestamp = now.toISOString(); const formatted = now.toLocaleString(); context.setData('timestamp', timestamp); context.setData('formattedDate', formatted);"
  }
}

Browser Interaction

{
  "type": "javascriptCode",
  "data": {
    "code": "const title = await context.page.title(); const url = context.page.url(); const content = await context.page.content(); context.setData('pageTitle', title); context.setData('pageUrl', url); context.setData('pageHtml', content);"
  }
}

API Data Processing

{
  "type": "javascriptCode",
  "data": {
    "code": "const response = context.getData('apiResponse'); const items = response.body.items; const ids = items.map(item => item.id); const names = items.map(item => item.name); context.setData('itemIds', ids); context.setData('itemNames', names); context.setData('itemCount', items.length);"
  }
}

Error Handling

Try-Catch Pattern
{
  "type": "javascriptCode",
  "data": {
    "code": "try { const data = JSON.parse(context.getData('jsonString')); context.setData('parsedData', data); context.setData('success', true); } catch (error) { console.error('Parse error:', error.message); context.setData('error', error.message); context.setData('success', false); }"
  }
}

Logging and Debugging

{
  "type": "javascriptCode",
  "data": {
    "code": "const users = context.getData('users'); console.log('Processing', users.length, 'users'); users.forEach((user, index) => { console.log(`${index + 1}. ${user.name} (${user.email})`); }); console.log('Processing complete');"
  }
}

Advanced Patterns

Async Operations

{
  "type": "javascriptCode",
  "data": {
    "code": "// Async operations with await const page = context.page; const elements = await page.$$('.item'); const texts = []; for (const el of elements) { const text = await el.textContent(); texts.push(text); } context.setData('extractedTexts', texts);"
  }
}

Custom Functions

{
  "type": "javascriptCode",
  "data": {
    "code": "// Define and use custom functions function calculateDiscount(price, percentage) { return price * (1 - percentage / 100); } const products = context.getData('products'); const discounted = products.map(p => ({ ...p, discountedPrice: calculateDiscount(parseFloat(p.price), 10) })); context.setData('discountedProducts', discounted);"
  }
}

Loop Alternative

{
  "type": "javascriptCode",
  "data": {
    "code": "// Process items without using Loop node const items = context.getData('items'); const results = []; for (const item of items) { // Process each item const processed = { id: item.id, value: item.value * 2 }; results.push(processed); } context.setData('processedItems', results);"
  }
}

Return Values

If the code returns a value, it’s stored in the context as result:
// In JavaScript Code node
const data = context.getData('someData');
return data.length; // Stored as 'result'

// Access in next node
const count = context.getData('result');

Notes

The code runs in an async function context, so you can use await for asynchronous operations without additional wrapping.
Avoid infinite loops or long-running operations as they can block workflow execution. Use timeouts and proper error handling.
The page object provides direct access to Playwright’s Page API, enabling advanced browser automation beyond what node-based operations provide.

Security Considerations

Production Deployments:
  • Implement code review processes
  • Restrict access to JavaScript Code nodes
  • Validate and sanitize all inputs
  • Avoid executing user-provided code
  • Use proper error handling to prevent information leakage

Common Use Cases

Data Transformation Pipeline

[
  { "type": "dataExtractor", "data": { ... } },
  {
    "type": "javascriptCode",
    "data": {
      "code": "const raw = context.getData('extractedData'); const cleaned = raw.map(item => ({ ...item, price: parseFloat(item.price.replace('$', '')), date: new Date(item.date).toISOString() })); context.setData('cleanedData', cleaned);"
    }
  },
  { "type": "apiRequest", "data": { ... } }
]

Conditional Workflow

[
  { "type": "elementQuery", "data": { ... } },
  {
    "type": "javascriptCode",
    "data": {
      "code": "const status = context.getData('elementText'); if (status.includes('error')) { context.setData('handleError', true); } else { context.setData('handleSuccess', true); }"
    }
  }
]

Build docs developers (and LLMs) love