DEV Community

Pirate Prentice
Pirate Prentice

Posted on

n8n Switch Node: Route Workflow Data to Multiple Branches (Free Workflow JSON)

n8n Switch Node: Route Workflow Data to Multiple Branches

If you need more than two paths — IF gives you true/false, but what if you have 4 different actions depending on a status field? That's exactly what the Switch node is built for.

In this guide I'll cover:

  • Switch node basics (rules vs expression mode)
  • Multi-output routing patterns
  • How to handle the "default" / fallthrough case
  • Real patterns: order status routing, lead scoring, webhook event dispatch
  • Free workflow JSON you can import directly

What the Switch Node Does

The Switch node evaluates each incoming item against a set of rules and routes it to the matching output. Unlike IF (2 outputs), Switch supports up to 25 outputs.

Two modes:

  • Rules mode — configure each output with a field + operator + value (no code)
  • Expression mode — write a JS expression that returns an output index (0-based)

Basic Setup: Order Status Routing

Scenario: you receive orders with a status field (pending, paid, cancelled, refunded). Route each to a different downstream action.

Switch node config (Rules mode):

Output Field Operator Value
0 {{ $json.status }} equals pending
1 {{ $json.status }} equals paid
2 {{ $json.status }} equals cancelled
3 {{ $json.status }} equals refunded

Each output connects to a different node (Send Slack alert, Trigger fulfillment, Update CRM, etc.).


The Fallthrough / Default Case

By default if no rule matches, the item is dropped silently. To catch unmatched items:

  1. Enable "Send data to all matching outputs" — off by default
  2. Or add a final output rule with a catch-all expression: {{ true }}

Best practice: always add a fallthrough output that logs or alerts on unexpected values.


Expression Mode: Dynamic Routing

When your routing logic is complex (contains math, multiple fields, lookups), use Expression mode:

// Route by lead score tier
const score = $json.lead_score;
if (score >= 80) return 0;      // Hot lead → Sales
if (score >= 50) return 1;      // Warm → Nurture sequence
if (score >= 20) return 2;      // Cold → Weekly digest
return 3;                        // Unscored → Manual review
Enter fullscreen mode Exit fullscreen mode

Expression mode returns a 0-based integer (output index). Returning null drops the item.


Pattern: Webhook Event Dispatcher

A common Switch use case is a webhook that receives multiple event types and fans out to specialized handlers:

Webhook → Switch (event type) →
  [0] payment.succeeded → Stripe fulfillment flow
  [1] payment.failed    → Retry / alert flow  
  [2] customer.created  → Onboarding flow
  [3] subscription.*    → Subscription management flow
  [default]             → Log unexpected event
Enter fullscreen mode Exit fullscreen mode

This keeps each event handler clean and independently maintainable.


Pattern: A/B Test Traffic Split

Use Expression mode for percentage-based splits:

// 20% A, 80% B split
return Math.random() < 0.2 ? 0 : 1;
Enter fullscreen mode Exit fullscreen mode

Or for a true 4-way split:

const r = Math.random();
if (r < 0.25) return 0;
if (r < 0.50) return 1;
if (r < 0.75) return 2;
return 3;
Enter fullscreen mode Exit fullscreen mode

Free Workflow JSON

Here's importable JSON for a Switch-based webhook event dispatcher:

{
  "name": "Switch Node — Webhook Event Dispatcher",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "events",
        "responseMode": "onReceived"
      },
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [240, 300]
    },
    {
      "parameters": {
        "mode": "rules",
        "rules": {
          "rules": [
            {
              "conditions": {
                "options": { "caseSensitive": true },
                "conditions": [
                  { "leftValue": "={{ $json.event }}", "rightValue": "payment.succeeded", "operator": { "type": "string", "operation": "equals" } }
                ]
              },
              "renameOutput": true,
              "outputKey": "payment_success"
            },
            {
              "conditions": {
                "options": { "caseSensitive": true },
                "conditions": [
                  { "leftValue": "={{ $json.event }}", "rightValue": "payment.failed", "operator": { "type": "string", "operation": "equals" } }
                ]
              },
              "renameOutput": true,
              "outputKey": "payment_failed"
            },
            {
              "conditions": {
                "options": { "caseSensitive": true },
                "conditions": [
                  { "leftValue": "={{ $json.event }}", "rightValue": "customer.created", "operator": { "type": "string", "operation": "equals" } }
                ]
              },
              "renameOutput": true,
              "outputKey": "customer_created"
            }
          ]
        },
        "fallbackOutput": "extra"
      },
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3,
      "position": [460, 300]
    },
    {
      "parameters": { "jsCode": "// Handle payment.succeeded
console.log('Payment succeeded:', $json);
return $input.all();" },
      "name": "Handle Payment Success",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [680, 180]
    },
    {
      "parameters": { "jsCode": "// Handle payment.failed
console.log('Payment failed:', $json);
return $input.all();" },
      "name": "Handle Payment Failed",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [680, 280]
    },
    {
      "parameters": { "jsCode": "// Handle customer.created
console.log('Customer created:', $json);
return $input.all();" },
      "name": "Handle Customer Created",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [680, 380]
    },
    {
      "parameters": { "jsCode": "// Fallthrough — unexpected event
console.warn('Unexpected event:', $json.event);
return $input.all();" },
      "name": "Log Unknown Event",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [680, 480]
    }
  ],
  "connections": {
    "Webhook": { "main": [[{ "node": "Switch", "type": "main", "index": 0 }]] },
    "Switch": {
      "main": [
        [{ "node": "Handle Payment Success", "type": "main", "index": 0 }],
        [{ "node": "Handle Payment Failed", "type": "main", "index": 0 }],
        [{ "node": "Handle Customer Created", "type": "main", "index": 0 }],
        [{ "node": "Log Unknown Event", "type": "main", "index": 0 }]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Import via Workflows → Import from JSON in your n8n instance.


Switch vs IF: When to Use Which

Scenario Use
Binary true/false IF node
3+ discrete values (status, type, tier) Switch node
Complex percentage splits Switch (Expression mode)
Nested conditions across multiple fields IF nodes chained, or Switch + IF combos

Common Gotchas

Items silently dropped: If no rule matches and you haven't added a fallthrough, items disappear. Always add a default output in production.

Output index vs output key: In Rules mode, outputs are indexed left-to-right (0, 1, 2…). Renaming an output with outputKey only changes the label — downstream nodes connect by position, not name.

typeVersion matters: Switch node typeVersion 3 uses the new Rules engine. If you're on an older n8n instance, you may have typeVersion 1 with different config structure.

Expression mode returns index, not value: Return 0, 1, 2 — not the branch name. A common mistake is returning "payment.succeeded" (string), which won't route correctly.


Troubleshooting

"All items going to output 0": Check your rule values — string comparison is case-sensitive by default. Enable case-insensitive matching in rule options if needed.

"Node has no output connections": You added a rule output but didn't wire it to a downstream node. n8n will warn but still run — items just drop after that output.

"Expression returned undefined": Your JS expression has a missing return or throws an error. Use the expression editor's preview to test against sample data.


More Free Workflow JSON

This is part of a series on every major n8n node. If you want a complete library of pre-built, documented workflow patterns — including Switch-based routers, error handlers, API integrations, and more — I put them together in one pack:

👉 n8n Workflow Starter Pack ($29) — 20+ ready-to-import workflows covering the most common automation patterns, each with setup instructions and comments.


Built something interesting with the Switch node? Drop your use case in the comments — especially creative multi-branch patterns or edge cases you've hit.

Top comments (1)

Collapse
 
pirateprentice profile image
Pirate Prentice

What do you use the Switch node for most? Webhook event routing, order status branching, or something else? Drop your use case below.