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
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
Retrieve data from the workflow context. const users = context . getData ( 'users' );
const apiResponse = context . getData ( 'apiResponse' );
context.setData(key, value)
Store data in the workflow context. context . setData ( 'processedUsers' , filteredUsers );
context . setData ( 'shouldContinue' , true );
Get a workflow variable (similar to getData). const itemId = context . getVariable ( 'currentItemId' );
context.setVariable(key, value)
Set a workflow variable. context . setVariable ( 'processCount' , count );
Get all data from the workflow context. const allData = context . getAllData ();
console . log ( 'Context data:' , allData );
context.getAllVariables()
Get all workflow variables. const allVars = context . getAllVariables ();
Page Access
Access the Playwright Page object for direct browser interaction. const title = await context . page . title ();
const url = context . page . url ();
Examples
Data Manipulation
Filter Array
Transform Data
Aggregate Data
{
"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
Simple Condition
Complex Logic
Validation
{
"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
Format Text
Extract Data
Parse JSON
{
"type" : "javascriptCode" ,
"data" : {
"code" : "const text = context.getData('rawText'); const formatted = text.trim().toLowerCase().replace(/ \\ s+/g, '-'); context.setData('formattedText', formatted);"
}
}
Date and Time
Current Timestamp
Date Calculations
Format Dates
{
"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
Get Page Info
Execute Page Script
Get Cookies
{
"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
Process Response
Build Request Body
{
"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
{
"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
Console Logging
Debug Context
{
"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
[
{ "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); }"
}
}
]