DEV Community

Pirate Prentice
Pirate Prentice

Posted on

n8n If Node: How to Add Conditional Logic to Your Workflows (Free Workflow JSON)

What the n8n If Node Does

The If node evaluates a condition on each incoming item and routes it to one of two outputs:

  • True branch — condition matched
  • False branch — condition did not match

It processes items one at a time. If your workflow receives 10 items and 3 match the condition, 3 go to the True branch and 7 go to the False branch — simultaneously, in the same execution.


Adding an If Node

  1. Open your workflow in n8n
  2. Click + after the node you want to branch from
  3. Search for If and select it
  4. Configure your condition in the node settings

Condition Types

The If node supports these value types:

Type Use for
String Text comparisons (equals, contains, starts with, regex)
Number Numeric comparisons (equal, greater than, less than)
Boolean True/false flags
Date & Time Before/after a timestamp
Array Contains an element
Object Has a key

Building a Condition

Each condition has three parts:

  1. Value 1 — the field you're evaluating (use expressions: {{ $json.status }})
  2. Operation — the comparison (equals, contains, greater than, etc.)
  3. Value 2 — what you're comparing against (can be a static value or another expression)

Example: Route based on order value

  • Value 1: {{ $json.amount }}
  • Operation: greater than
  • Value 2: 100

Items with amount > 100 go to True; everything else goes to False.


Combining Conditions (AND / OR)

Click Add condition to chain multiple rules:

  • AND — all conditions must be true for an item to go to True branch
  • OR — any one condition being true routes to True branch

Switch between AND/OR with the toggle above the condition list.

Example: High-value lead from a specific source

{{ $json.lead_value }} greater than 500
AND
{{ $json.source }} equals "organic"
Enter fullscreen mode Exit fullscreen mode

Only leads worth over $500 that came from organic traffic hit the True branch.


Using Expressions in Conditions

Expressions let you compare dynamic values, not just static ones.

Check if a field exists:

  • Value 1: {{ $json.email }}
  • Operation: is not empty

Case-insensitive string match:

  • Value 1: {{ $json.status.toLowerCase() }}
  • Operation: equals
  • Value 2: active

Compare two dynamic fields:

  • Value 1: {{ $json.submitted_at }}
  • Operation: greater than
  • Value 2: {{ $json.deadline }}

What Happens to Unmatched Items

Items that don't match go to the False branch. You have three choices for what to do with them:

  1. Connect a node — process the False branch differently (e.g., send a rejection email)
  2. Leave it unconnected — False-branch items are silently dropped
  3. Connect to the same downstream node — merge both branches into one output

To merge both branches, connect the True and False outputs to the same node. n8n will combine the items automatically.


Practical Example: Duplicate Lead Filter

Scenario: Your webhook receives form submissions. You want to check if the email already exists in Google Sheets before adding it.

Workflow structure:

Webhook → Google Sheets (lookup) → If Node → [True: Skip] [False: Append Row + Send Welcome Email]
Enter fullscreen mode Exit fullscreen mode

If node condition:

  • Value 1: {{ $json.email }}
  • Operation: is not empty
  • (True = email found in sheet → skip; False = new lead → add)

This prevents duplicate rows without any custom code.


Free Workflow JSON: Lead Deduplication with If Node

Here's a complete workflow you can import directly into n8n. It:

  1. Receives a webhook with name, email, and source fields
  2. Looks up the email in Google Sheets
  3. Uses an If node to check if a row was found
  4. If duplicate → logs and stops; if new → appends the row and sends a welcome email via Gmail
{
  "name": "Lead Dedup with If Node",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "lead-intake",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "webhook-1",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [240, 300]
    },
    {
      "parameters": {
        "operation": "lookup",
        "documentId": { "__rl": true, "value": "YOUR_SHEET_ID", "mode": "id" },
        "sheetName": { "__rl": true, "value": "Sheet1", "mode": "name" },
        "lookupColumn": "Email",
        "lookupValue": "={{ $json.body.email }}"
      },
      "id": "sheets-lookup",
      "name": "Sheets Lookup",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4,
      "position": [460, 300]
    },
    {
      "parameters": {
        "conditions": {
          "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict" },
          "conditions": [
            {
              "id": "cond-1",
              "leftValue": "={{ $json.email }}",
              "rightValue": "",
              "operator": { "type": "string", "operation": "notEmpty" }
            }
          ],
          "combinator": "and"
        }
      },
      "id": "if-node",
      "name": "Is Duplicate?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [680, 300]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": { "__rl": true, "value": "YOUR_SHEET_ID", "mode": "id" },
        "sheetName": { "__rl": true, "value": "Sheet1", "mode": "name" },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Name": "={{ $('Webhook').item.json.body.name }}",
            "Email": "={{ $('Webhook').item.json.body.email }}",
            "Source": "={{ $('Webhook').item.json.body.source }}",
            "Added": "={{ $now.toISO() }}"
          }
        }
      },
      "id": "sheets-append",
      "name": "Append New Lead",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4,
      "position": [900, 200]
    },
    {
      "parameters": {
        "sendTo": "={{ $('Webhook').item.json.body.email }}",
        "subject": "Welcome — you're on the list",
        "message": "Hi {{ $('Webhook').item.json.body.name }},\n\nThanks for signing up. We'll be in touch soon.\n\nCheers",
        "options": {}
      },
      "id": "gmail-welcome",
      "name": "Send Welcome Email",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2,
      "position": [1120, 200]
    }
  ],
  "connections": {
    "Webhook": { "main": [[{ "node": "Sheets Lookup", "type": "main", "index": 0 }]] },
    "Sheets Lookup": { "main": [[{ "node": "Is Duplicate?", "type": "main", "index": 0 }]] },
    "Is Duplicate?": {
      "main": [
        [],
        [{ "node": "Append New Lead", "type": "main", "index": 0 }]
      ]
    },
    "Append New Lead": { "main": [[{ "node": "Send Welcome Email", "type": "main", "index": 0 }]] }
  },
  "active": false,
  "settings": { "executionOrder": "v1" }
}
Enter fullscreen mode Exit fullscreen mode

To use it:

  1. In n8n: Workflows → Import from clipboard → paste the JSON
  2. Replace YOUR_SHEET_ID with your Google Sheet's ID (from its URL)
  3. Connect your Google Sheets and Gmail credentials
  4. Activate and test with a POST to your webhook URL

Common If Node Mistakes

1. Confusing empty string with null

An empty string ("") and a missing field (null) both look "empty" visually but behave differently. Use is not empty (not is not equal to "") to catch both.

2. Type mismatch

Comparing {{ $json.amount }} (which arrives as a string from a webhook) to a number using greater than will fail silently or return unexpected results. Cast it: {{ Number($json.amount) }}.

3. Both branches unconnected

If you add an If node but forget to wire both outputs, one path will dead-end silently. Always check the False branch is handled intentionally.


When to Use Switch Instead

The If node is binary — True or False. If you need more than two paths (e.g., route by plan_type = free, pro, enterprise), use the Switch node instead. It evaluates multiple conditions and routes to a matching output.


Want More Workflows Like This?

I put together a Starter Pack of 10 production-ready n8n workflows — each with setup guides and JSON you can import in under 10 minutes:

  • Lead capture → CRM → welcome email (with deduplication)
  • Stripe payment → fulfillment trigger → receipt email
  • Form submission → Google Sheets + Slack alert
  • Webhook router with If/Switch branching
  • Scheduled data sync with error logging
  • And 5 more

→ n8n Workflow Starter Pack ($29)

One-time purchase. No subscription. Instant download.


Discussion

What's the most useful conditional logic you've built in n8n? I'm planning the next pack around real use cases — drop your most-requested workflow in the comments.

Top comments (1)

Collapse
 
pirateprentice profile image
Pirate Prentice

What conditional logic do you use most in your n8n workflows? For me it's the duplicate-check pattern (lookup → If node → skip or add) — saves so much manual cleanup. Drop your most-used If node setup in the comments, I'm building the next workflow pack around real use cases.