The IF node is one of the most fundamental and powerful components in n8n for creating intelligent, decision-making workflows. This comprehensive guide will teach you everything you need to know about implementing conditional logic, from basic comparisons to complex nested conditions and advanced patterns.
Understanding Conditional Logic in n8n
Conditional logic allows workflows to make decisions based on data, creating dynamic automation that responds intelligently to different scenarios. The IF node serves as the primary decision-making component in n8n workflows.
What is the IF Node?
The IF node evaluates conditions and routes data down one of two paths:
- True path: When conditions are met
- False path: When conditions are not met
Key Concepts:
- Conditions: Logical tests that evaluate to true or false
- Data Types: Different types of data require different comparison operations
- Operators: Comparison methods (equals, contains, greater than, etc.)
- Branching: Splitting workflow execution based on conditions
- Data Flow: How data moves through conditional branches
Basic IF Node Configuration
Adding an IF Node
// Basic IF node setup process
1. Add IF node to your workflow
2. Connect it to a previous node with data
3. Configure conditions in the node parameters
4. Connect true/false outputs to subsequent nodes
Understanding the Interface
Condition Builder:
// IF node condition structure
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"operation": "equal",
"rightValue": ""
}
},
"combineOperation": "and" // or "or"
}
Data Type Selection:
- String: Text-based comparisons
- Number: Numeric comparisons
- Date & Time: Temporal comparisons
- Boolean: True/false evaluations
- Array: List-based operations
- Object: Object existence checks
Data Type Comparisons and Operations
String Operations
Basic String Comparisons:
// String comparison examples
const stringConditions = {
"exists": "{{ $json.name }}", // Check if field exists
"isEmpty": "{{ $json.description }}", // Check if empty
"equals": {
"value1": "{{ $json.status }}",
"value2": "active"
},
"contains": {
"value1": "{{ $json.email }}",
"value2": "@company.com"
},
"startsWith": {
"value1": "{{ $json.productCode }}",
"value2": "PRD-"
},
"endsWith": {
"value1": "{{ $json.filename }}",
"value2": ".pdf"
}
};
Advanced String Operations:
// Regular expression matching
const regexConditions = {
"emailValidation": {
"value1": "{{ $json.email }}",
"operation": "regex",
"value2": "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$"
},
"phoneValidation": {
"value1": "{{ $json.phone }}",
"operation": "regex",
"value2": "^\\+?[1-9]\\d{1,14}$"
},
"caseInsensitive": {
"value1": "{{ $json.category.toLowerCase() }}",
"operation": "equal",
"value2": "premium"
}
};
Number Operations
Numeric Comparisons:
// Number comparison examples
const numberConditions = {
"greaterThan": {
"value1": "{{ $json.price }}",
"operation": "largerEqual",
"value2": 100
},
"range": {
"condition1": {
"value1": "{{ $json.age }}",
"operation": "larger",
"value2": 18
},
"combineOperation": "and",
"condition2": {
"value1": "{{ $json.age }}",
"operation": "smaller",
"value2": 65
}
},
"calculation": {
"value1": "{{ $json.quantity * $json.unitPrice }}",
"operation": "larger",
"value2": 1000
}
};
Mathematical Expressions:
// Complex numeric conditions
const mathConditions = {
"percentage": {
"value1": "{{ ($json.completed / $json.total) * 100 }}",
"operation": "largerEqual",
"value2": 75
},
"average": {
"value1": "{{ $json.scores.reduce((a, b) => a + b, 0) / $json.scores.length }}",
"operation": "larger",
"value2": 80
},
"roundedValue": {
"value1": "{{ Math.round($json.rating * 10) / 10 }}",
"operation": "equal",
"value2": 4.5
}
};
Date and Time Operations
Date Comparisons:
// Date and time conditions
const dateConditions = {
"isToday": {
"value1": "{{ $json.createdAt }}",
"operation": "equal",
"value2": "{{ $today }}"
},
"withinLastWeek": {
"value1": "{{ $json.lastLogin }}",
"operation": "after",
"value2": "{{ $today.minus(7, 'days') }}"
},
"businessHours": {
"condition1": {
"value1": "{{ $now.hour }}",
"operation": "largerEqual",
"value2": 9
},
"combineOperation": "and",
"condition2": {
"value1": "{{ $now.hour }}",
"operation": "smaller",
"value2": 17
}
},
"weekday": {
"value1": "{{ $now.weekday }}",
"operation": "smallerEqual",
"value2": 5
}
};
Advanced Date Logic:
// Complex date conditions
const advancedDateConditions = {
"monthEnd": {
"value1": "{{ $today.endOf('month').diff($today, 'days') }}",
"operation": "smallerEqual",
"value2": 3
},
"quarterStart": {
"value1": "{{ $today.quarter }}",
"operation": "notEqual",
"value2": "{{ $today.minus(1, 'month').quarter }}"
},
"anniversary": {
"value1": "{{ DateTime.fromISO($json.startDate).toFormat('MM-dd') }}",
"operation": "equal",
"value2": "{{ $today.toFormat('MM-dd') }}"
}
};
Boolean Operations
Boolean Logic:
// Boolean conditions
const booleanConditions = {
"isActive": {
"value1": "{{ $json.active }}",
"operation": "equal",
"value2": true
},
"hasPermission": {
"value1": "{{ $json.permissions.includes('admin') }}",
"operation": "equal",
"value2": true
},
"flagCombination": {
"condition1": {
"value1": "{{ $json.isVerified }}",
"operation": "equal",
"value2": true
},
"combineOperation": "and",
"condition2": {
"value1": "{{ $json.isActive }}",
"operation": "equal",
"value2": true
}
}
};
Array Operations
Array Conditions:
// Array-based conditions
const arrayConditions = {
"hasItems": {
"value1": "{{ $json.items }}",
"operation": "notEmpty"
},
"arrayLength": {
"value1": "{{ $json.tags.length }}",
"operation": "larger",
"value2": 0
},
"containsValue": {
"value1": "{{ $json.categories }}",
"operation": "contains",
"value2": "premium"
},
"arraySize": {
"value1": "{{ $json.attachments.length }}",
"operation": "smallerEqual",
"value2": 5
}
};
Complex Array Logic:
// Advanced array operations
const complexArrayConditions = {
"allItemsMatch": {
"value1": "{{ $json.items.every(item => item.status === 'completed') }}",
"operation": "equal",
"value2": true
},
"someItemsMatch": {
"value1": "{{ $json.products.some(product => product.price > 100) }}",
"operation": "equal",
"value2": true
},
"uniqueValues": {
"value1": "{{ new Set($json.userIds).size }}",
"operation": "equal",
"value2": "{{ $json.userIds.length }}"
}
};
Combining Multiple Conditions
AND Logic
All Conditions Must Be True:
// AND combination example
const andConditions = {
"condition1": {
"value1": "{{ $json.age }}",
"operation": "largerEqual",
"value2": 18
},
"combineOperation": "and",
"condition2": {
"value1": "{{ $json.country }}",
"operation": "equal",
"value2": "US"
},
"condition3": {
"value1": "{{ $json.verified }}",
"operation": "equal",
"value2": true
}
};
// Use case: User eligibility check
// Only proceed if user is 18+, from US, and verified
OR Logic
Any Condition Can Be True:
// OR combination example
const orConditions = {
"condition1": {
"value1": "{{ $json.priority }}",
"operation": "equal",
"value2": "urgent"
},
"combineOperation": "or",
"condition2": {
"value1": "{{ $json.customerTier }}",
"operation": "equal",
"value2": "premium"
},
"condition3": {
"value1": "{{ $json.amount }}",
"operation": "larger",
"value2": 10000
}
};
// Use case: Priority handling
// Route to priority queue if urgent, premium customer, or large amount
Complex Condition Combinations
Mixed Logic Patterns:
// Complex condition example
const complexConditions = {
// (A AND B) OR (C AND D)
"group1": {
"condition1": {
"value1": "{{ $json.type }}",
"operation": "equal",
"value2": "enterprise"
},
"combineOperation": "and",
"condition2": {
"value1": "{{ $json.contract }}",
"operation": "equal",
"value2": "active"
}
},
"mainCombine": "or",
"group2": {
"condition1": {
"value1": "{{ $json.revenue }}",
"operation": "larger",
"value2": 50000
},
"combineOperation": "and",
"condition2": {
"value1": "{{ $json.relationship }}",
"operation": "equal",
"value2": "strategic"
}
}
};
Advanced Conditional Patterns
1. Nested IF Logic
Cascading Decisions:
// Workflow pattern: Nested IF nodes
const nestedPattern = {
"firstLevel": {
"condition": "{{ $json.userType }}",
"operation": "equal",
"value": "premium",
"truePath": {
"secondLevel": {
"condition": "{{ $json.subscriptionStatus }}",
"operation": "equal",
"value": "active",
"truePath": "Premium Active Flow",
"falsePath": "Premium Inactive Flow"
}
},
"falsePath": {
"secondLevel": {
"condition": "{{ $json.trialExpired }}",
"operation": "equal",
"value": false,
"truePath": "Trial Active Flow",
"falsePath": "Free User Flow"
}
}
}
};
Implementation Example:
// Customer segmentation workflow
Manual Trigger →
Get Customer Data →
IF: Customer Type = "Enterprise" →
True: IF: Contract Status = "Active" →
True: Enterprise Active Process
False: Enterprise Renewal Process
False: IF: Revenue > $10,000 →
True: Upsell Process
False: Standard Process
2. Multi-Path Routing
Using Multiple IF Nodes:
// Multi-path routing pattern
const multiPathRouting = {
"priorityCheck": {
"condition": "{{ $json.priority }}",
"paths": {
"critical": "IF: priority = 'critical' → Critical Handler",
"high": "IF: priority = 'high' → High Priority Handler",
"normal": "IF: priority = 'normal' → Normal Handler",
"low": "Default → Low Priority Handler"
}
}
};
Switch Node Alternative:
// When to use Switch vs multiple IFs
const decisionMatrix = {
"useIF": [
"Binary decisions (true/false)",
"Complex condition combinations",
"When you need AND/OR logic",
"Two output paths maximum"
],
"useSwitch": [
"Multiple discrete values",
"More than two output paths",
"Simple value matching",
"Cleaner visual representation"
]
};
3. Data Validation Patterns
Input Validation Chain:
// Data validation workflow
const validationChain = {
"step1": {
"node": "IF: Email Format Valid",
"condition": "{{ /^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$/.test($json.email) }}",
"truePath": "Continue to Step 2",
"falsePath": "Return Email Error"
},
"step2": {
"node": "IF: Required Fields Present",
"condition": "{{ $json.name && $json.phone && $json.address }}",
"truePath": "Continue to Step 3",
"falsePath": "Return Missing Fields Error"
},
"step3": {
"node": "IF: Age Validation",
"condition": "{{ $json.age >= 18 && $json.age <= 120 }}",
"truePath": "Process Valid Data",
"falsePath": "Return Age Error"
}
};
4. Business Rule Implementation
Complex Business Logic:
// Pricing logic example
const pricingLogic = {
"volumeDiscount": {
"condition": "{{ $json.quantity >= 100 }}",
"truePath": {
"tierCheck": {
"condition": "{{ $json.customerTier === 'gold' }}",
"truePath": "Apply 25% discount",
"falsePath": "Apply 15% discount"
}
},
"falsePath": {
"loyaltyCheck": {
"condition": "{{ $json.loyaltyYears >= 5 }}",
"truePath": "Apply 10% discount",
"falsePath": "No discount"
}
}
}
};
Approval Workflow:
// Multi-level approval logic
const approvalWorkflow = {
"amountCheck": {
"condition": "{{ $json.amount <= 1000 }}",
"truePath": "Auto-approve",
"falsePath": {
"managerApproval": {
"condition": "{{ $json.amount <= 10000 }}",
"truePath": "Send to Manager",
"falsePath": {
"directorApproval": {
"condition": "{{ $json.amount <= 50000 }}",
"truePath": "Send to Director",
"falsePath": "Send to Board"
}
}
}
}
}
};
Working with Expressions in IF Nodes
Dynamic Conditions
Expression-Based Conditions:
// Dynamic condition examples
const dynamicConditions = {
"timeBasedLogic": {
"condition": "{{ $now.hour >= 9 && $now.hour < 17 && $now.weekday <= 5 }}",
"description": "Business hours check"
},
"calculatedValues": {
"condition": "{{ ($json.totalSales / $json.target) * 100 >= 80 }}",
"description": "Sales target achievement"
},
"arrayOperations": {
"condition": "{{ $json.tags.includes('vip') || $json.purchaseHistory.length > 10 }}",
"description": "VIP customer identification"
},
"stringManipulation": {
"condition": "{{ $json.email.split('@')[1] === 'company.com' }}",
"description": "Internal email check"
}
};
Advanced Expression Patterns
Conditional Expressions Within IF Nodes:
// Nested conditional logic in expressions
const advancedExpressions = {
"conditionalValue": {
"condition": "{{ $json.type === 'premium' ? $json.premiumLimit : $json.standardLimit }}",
"operation": "larger",
"value2": "{{ $json.currentUsage }}"
},
"multipleChecks": {
"condition": "{{ ['active', 'trial', 'grace'].includes($json.status) && $json.lastLogin > $today.minus(30, 'days') }}",
"description": "Active user check"
},
"complexCalculation": {
"condition": "{{ Math.max(...$json.scores) >= 85 && $json.scores.filter(s => s >= 70).length >= 3 }}",
"description": "Performance criteria"
}
};
Error Handling in Conditions
Safe Expression Evaluation:
// Error-safe conditions
const safeConditions = {
"nullSafeCheck": {
"condition": "{{ $json.user?.profile?.email || '' }}",
"operation": "contains",
"value2": "@company.com"
},
"arrayLengthSafe": {
"condition": "{{ ($json.items || []).length }}",
"operation": "larger",
"value2": 0
},
"numberSafe": {
"condition": "{{ Number($json.price) || 0 }}",
"operation": "larger",
"value2": 100
},
"dateSafe": {
"condition": "{{ $json.date ? DateTime.fromISO($json.date).isValid : false }}",
"operation": "equal",
"value2": true
}
};
Performance Optimization
Efficient Condition Design
Optimization Strategies:
// Performance best practices
const optimizationTips = {
"orderConditions": {
"principle": "Place most likely to fail conditions first",
"example": {
"inefficient": "Complex calculation AND simple check",
"efficient": "Simple check AND complex calculation"
}
},
"cacheCalculations": {
"principle": "Pre-calculate complex values",
"example": {
"before": "{{ complexFunction($json.data) > threshold }}",
"after": "Use Set node to calculate, then simple comparison"
}
},
"avoidRepeatedWork": {
"principle": "Don't repeat expensive operations",
"solution": "Calculate once, store in variable, reference multiple times"
}
};
Condition Simplification:
// Simplify complex conditions
const simplificationExamples = {
"before": {
"condition1": "{{ $json.status === 'active' }}",
"combineOperation": "and",
"condition2": "{{ $json.verified === true }}",
"condition3": "{{ $json.type === 'premium' }}"
},
"after": {
"condition": "{{ $json.status === 'active' && $json.verified && $json.type === 'premium' }}"
}
};
Memory and Processing Considerations
Large Dataset Handling:
// Handling large datasets efficiently
const largeDataPatterns = {
"earlyFiltering": {
"pattern": "Filter data as early as possible",
"implementation": "Use IF nodes before expensive operations"
},
"batchProcessing": {
"pattern": "Process data in batches",
"implementation": "Split large arrays before conditional logic"
},
"indexedAccess": {
"pattern": "Use indexed access for large objects",
"implementation": "{{ $json.lookup[key] }} instead of array.find()"
}
};
Common Patterns and Use Cases
1. User Authentication and Authorization
Authentication Flow:
// User authentication workflow
const authFlow = {
"workflow": [
{
"node": "Webhook Trigger",
"output": "User credentials"
},
{
"node": "IF: Credentials Present",
"condition": "{{ $json.username && $json.password }}",
"truePath": "Validate Credentials",
"falsePath": "Return 401 Unauthorized"
},
{
"node": "Validate Credentials",
"output": "User data or null"
},
{
"node": "IF: Valid User",
"condition": "{{ $json.user !== null }}",
"truePath": "Check Permissions",
"falsePath": "Return 401 Invalid Credentials"
},
{
"node": "IF: Has Required Permission",
"condition": "{{ $json.user.permissions.includes($json.requiredPermission) }}",
"truePath": "Grant Access",
"falsePath": "Return 403 Forbidden"
}
]
};
2. E-commerce Order Processing
Order Validation and Routing:
// E-commerce order processing
const orderProcessing = {
"inventoryCheck": {
"condition": "{{ $json.items.every(item => item.stock >= item.quantity) }}",
"truePath": "Continue Processing",
"falsePath": "Backorder Process"
},
"paymentValidation": {
"condition": "{{ $json.payment.status === 'authorized' && $json.payment.amount === $json.total }}",
"truePath": "Process Order",
"falsePath": "Payment Error Handler"
},
"shippingLogic": {
"condition": "{{ $json.total >= 50 || $json.customer.tier === 'premium' }}",
"truePath": "Free Shipping",
"falsePath": "Calculate Shipping"
},
"fulfillmentRouting": {
"condition": "{{ $json.items.some(item => item.category === 'digital') }}",
"truePath": "Mixed Fulfillment",
"falsePath": "Physical Fulfillment"
}
};
3. Content Management and Moderation
Content Approval Workflow:
// Content moderation system
const contentModeration = {
"autoModeration": {
"condition": "{{ $json.content.length > 0 && !$json.flaggedWords.some(word => $json.content.toLowerCase().includes(word)) }}",
"truePath": "Continue Review",
"falsePath": "Auto-reject"
},
"authorCheck": {
"condition": "{{ $json.author.reputation >= 100 && $json.author.violations === 0 }}",
"truePath": "Auto-approve",
"falsePath": "Manual Review"
},
"contentType": {
"condition": "{{ ['image', 'video'].includes($json.type) }}",
"truePath": "Media Review Process",
"falsePath": "Text Review Process"
}
};
4. Data Quality and Validation
Data Quality Checks:
// Data quality validation
const dataQuality = {
"completenessCheck": {
"condition": "{{ Object.values($json.record).every(value => value !== null && value !== '') }}",
"truePath": "Complete Record",
"falsePath": "Incomplete Data Handler"
},
"formatValidation": {
"condition": "{{ /^\\d{4}-\\d{2}-\\d{2}$/.test($json.date) && /^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$/.test($json.email) }}",
"truePath": "Valid Format",
"falsePath": "Format Error Handler"
},
"businessRules": {
"condition": "{{ $json.startDate <= $json.endDate && $json.price > 0 && $json.quantity > 0 }}",
"truePath": "Valid Business Data",
"falsePath": "Business Rule Violation"
}
};
Troubleshooting Common Issues
1. Condition Evaluation Problems
Common Issues and Solutions:
// Troubleshooting guide
const troubleshooting = {
"typeCoercion": {
"problem": "String '5' not equal to number 5",
"solution": "{{ Number($json.value) === 5 }} or {{ String($json.value) === '5' }}"
},
"nullUndefined": {
"problem": "Null/undefined causing errors",
"solution": "{{ $json.field || 'default' }} or {{ $json.field ?? 'default' }}"
},
"arrayEmpty": {
"problem": "Empty array evaluation",
"solution": "{{ ($json.array || []).length > 0 }}"
},
"dateComparison": {
"problem": "Date string comparison issues",
"solution": "{{ DateTime.fromISO($json.date) > DateTime.fromISO('2024-01-01') }}"
}
};
2. Performance Issues
Optimization Techniques:
// Performance troubleshooting
const performanceIssues = {
"slowConditions": {
"problem": "Complex expressions causing delays",
"solutions": [
"Pre-calculate values in Set node",
"Use simpler conditions when possible",
"Cache repeated calculations"
]
},
"memoryUsage": {
"problem": "High memory usage with large datasets",
"solutions": [
"Filter data early in workflow",
"Use batch processing",
"Avoid storing large objects in variables"
]
}
};
3. Logic Errors
Common Logic Mistakes:
// Logic error patterns
const logicErrors = {
"negationConfusion": {
"problem": "Double negatives or incorrect NOT logic",
"example": "NOT (A AND B) ≠ (NOT A) AND (NOT B)",
"solution": "Use De Morgan's laws: NOT (A AND B) = (NOT A) OR (NOT B)"
},
"shortCircuiting": {
"problem": "Expecting all conditions to evaluate",
"explanation": "AND stops at first false, OR stops at first true",
"solution": "Order conditions appropriately"
},
"typeComparison": {
"problem": "Comparing different data types",
"solution": "Ensure consistent data types in comparisons"
}
};
Best Practices and Design Patterns
1. Readable Condition Design
Clear Naming and Documentation:
// Best practices for condition clarity
const clarityPractices = {
"descriptiveNames": {
"bad": "IF Node",
"good": "IF: User Is Premium Customer"
},
"comments": {
"practice": "Add notes explaining complex conditions",
"example": "Check if user qualifies for premium features based on subscription and usage"
},
"grouping": {
"practice": "Group related conditions logically",
"example": "User validation → Business rules → Output routing"
}
};
2. Maintainable Condition Logic
Modular Design:
// Maintainable condition patterns
const maintainabilityPatterns = {
"singleResponsibility": {
"principle": "Each IF node should check one logical concept",
"example": "Separate user validation from business rule checking"
},
"consistentStyle": {
"principle": "Use consistent expression patterns",
"example": "Always use same null-checking approach"
},
"errorHandling": {
"principle": "Handle edge cases explicitly",
"example": "Check for null/undefined before operations"
}
};
3. Testing and Validation
Testing Strategies:
// Testing conditional logic
const testingStrategies = {
"edgeCases": [
"Null/undefined values",
"Empty arrays/objects",
"Boundary values (0, negative numbers)",
"Invalid date formats",
"Special characters in strings"
],
"testData": {
"practice": "Create comprehensive test datasets",
"coverage": "Test both true and false paths",
"automation": "Use manual triggers with test data"
},
"validation": {
"practice": "Validate condition logic before deployment",
"tools": "Use debug nodes to trace execution paths"
}
};
Advanced Integration Patterns
1. IF Nodes with Sub-Workflows
Conditional Sub-Workflow Execution:
// Conditional sub-workflow pattern
const conditionalSubWorkflows = {
"pattern": "IF → Execute Sub-workflow",
"useCase": "Complex processing only when needed",
"example": {
"condition": "{{ $json.requiresComplexProcessing }}",
"truePath": "Execute Sub-workflow: Complex Data Processing",
"falsePath": "Execute Sub-workflow: Simple Data Processing"
}
};
2. Dynamic Workflow Routing
Runtime Decision Making:
// Dynamic routing based on data
const dynamicRouting = {
"workflowSelection": {
"condition": "{{ $json.processingType }}",
"routing": {
"batch": "Execute Sub-workflow: Batch Processor",
"realtime": "Execute Sub-workflow: Realtime Processor",
"scheduled": "Execute Sub-workflow: Scheduled Processor"
}
}
};
Conclusion
The IF node is a fundamental building block for creating intelligent, responsive workflows in n8n. By mastering conditional logic patterns, you can build sophisticated automation that adapts to different scenarios and makes smart decisions based on your data.
Key takeaways for effective IF node usage:
- Understand Data Types: Choose the right comparison operations for your data
- Design Clear Conditions: Write readable, maintainable conditional logic
Top comments (0)