Skip to main content

Scripts & Pixels per Step

Time: ~10 minutes | Difficulty: Intermediate

What Is Step Config?

Every step in a funnel can have its own runtime configuration — tracking pixels, custom scripts, payment flow overrides, and order bumps. This is set inside node.config.stepConfig.
Funnel
 ├── step-landing     → stepConfig: { pixels: { facebook: [...] } }
 ├── step-checkout    → stepConfig: { pixels: {...}, scripts: [...], paymentSetupConfig: { card: { paymentFlowId: "..." } } }
 └── step-thankyou    → stepConfig: { pixels: { facebook: [...] }, scripts: [...] }
Why per-step? Different steps fire different events. Your landing page tracks PageView, your checkout tracks InitiateCheckout and Purchase, and your thank-you page tracks the conversion. Each step can have completely different pixels and scripts.

Step Config Structure

node.config.stepConfig = {
  // Tracking pixels (Meta, TikTok, Snapchat, GTM, etc.)
  pixels: { ... },

  // Custom script injection (any JS)
  scripts: [ ... ],

  // Payment methods displayed at checkout (cards, wallets, APMs)
  paymentSetupConfig: {
    card: { enabled: true, method: 'card', provider: 'tagada', paymentFlowId: 'flow_xxx' },
    apple_pay: { enabled: true, method: 'apple_pay', provider: 'stripe', express: true, processorId: 'processor_xxx' },
    // ...more methods
  },

  // Order bumps (checkout steps only)
  orderBumps: { mode: 'inherit' | 'custom', enabledOfferIds: [...] },
};

Tracking Pixels

Pixels are keyed by provider. Each provider can have multiple pixels (array).

Meta / Facebook Pixel

stepConfig: {
  pixels: {
    facebook: [
      {
        enabled: true,
        pixelId: '123456789012345',
        events: {
          PageView: true,
          InitiateCheckout: true,
          Purchase: true,
        },
      },
    ],
  },
}

Meta Conversion API (server-side)

stepConfig: {
  pixels: {
    metaConversion: [
      {
        enabled: true,
        pixelId: '123456789012345',
        accessToken: 'EAABsbCS...',
        publishPurchaseIfNewCustomerOnly: false,
      },
    ],
  },
}

TikTok Pixel

stepConfig: {
  pixels: {
    tiktok: [
      {
        enabled: true,
        pixelId: 'CTJDE3RC77U...',
        events: {
          PageView: true,
          InitiateCheckout: true,
          Purchase: true,
        },
      },
    ],
  },
}

Snapchat Pixel

stepConfig: {
  pixels: {
    snapchat: [
      {
        enabled: true,
        pixelId: 'abc123...',
        events: {
          PageView: true,
          InitiateCheckout: true,
          Purchase: true,
          AddToCart: true,
          ViewContent: true,
          Search: false,
          AddToWishlist: false,
          CompleteRegistration: false,
        },
      },
    ],
  },
}

Google Tag Manager

stepConfig: {
  pixels: {
    gtm: [
      {
        enabled: true,
        containerId: 'GTM-XXXXXXX',
        events: {
          PageView: true,
          InitiateCheckout: true,
          Purchase: true,
          AddToCart: true,
          ViewContent: true,
        },
        googleAdsConversionId: 'AW-123456789',
        googleAdsConversionLabel: 'abcDEF123',
      },
    ],
  },
}

Custom Scripts

Inject any JavaScript into funnel pages. Each script has a name, content, and injection position.
stepConfig: {
  scripts: [
    {
      name: 'Hotjar',
      enabled: true,
      content: `(function(h,o,t,j,a,r){h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};h._hjSettings={hjid:12345,hjsv:6};a=o.getElementsByTagName('head')[0];r=o.createElement('script');r.async=1;r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;a.appendChild(r);})(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');`,
      position: 'head-end',
    },
    {
      name: 'Custom conversion',
      enabled: true,
      content: `console.log('Step loaded:', window.__TGD_FUNNEL_STEP_ID__);`,
      position: 'body-end',
    },
  ],
}
PositionWhere it’s injected
head-startFirst thing inside <head>
head-endLast thing inside <head> (default)
body-startFirst thing inside <body>
body-endLast thing inside <body>

Full Example: 3-Step Funnel with Tracking

Here’s a complete Node SDK example that creates a funnel with Meta Pixel + TikTok on every step, plus GTM on checkout only.
import Tagada from '@tagadapay/node-sdk';

const tagada = new Tagada('your-api-key');

const META_PIXEL = '123456789012345';
const TIKTOK_PIXEL = 'CTJDE3RC77U...';
const GTM_CONTAINER = 'GTM-XXXXXXX';

const storeId = 'store_xxx';
const pluginId = 'my-checkout-plugin';
const instanceId = 'my-instance-id';

// Helper: Meta pixel config for a step
const metaPixel = (events: Record<string, boolean>) => ({
  facebook: [{
    enabled: true,
    pixelId: META_PIXEL,
    events: { PageView: false, InitiateCheckout: false, Purchase: false, ...events },
  }],
});

// Helper: TikTok pixel config for a step
const tiktokPixel = (events: Record<string, boolean>) => ({
  tiktok: [{
    enabled: true,
    pixelId: TIKTOK_PIXEL,
    events: { PageView: false, InitiateCheckout: false, Purchase: false, ...events },
  }],
});

const funnel = await tagada.funnels.create({
  storeId,
  config: {
    id: 'my-tracked-funnel',
    name: 'Tracked Checkout Funnel',
    version: '1.0.0',
    nodes: [
      {
        id: 'step-landing',
        name: 'Landing Page',
        type: 'landing',
        isEntry: true,
        isDefault: true,
        position: { x: 0, y: 0 },
        config: {
          pluginId, instanceId,
          pagePath: '/', path: '/',
          stepConfig: {
            pixels: {
              ...metaPixel({ PageView: true }),
              ...tiktokPixel({ PageView: true }),
            },
          },
        },
      },
      {
        id: 'step-checkout',
        name: 'Checkout',
        type: 'checkout',
        isConversion: true,
        position: { x: 300, y: 0 },
        config: {
          pluginId, instanceId,
          pagePath: '/checkout', path: '/checkout',
          stepConfig: {
            pixels: {
              ...metaPixel({ InitiateCheckout: true, Purchase: true }),
              ...tiktokPixel({ InitiateCheckout: true, Purchase: true }),
              gtm: [{
                enabled: true,
                containerId: GTM_CONTAINER,
                events: {
                  PageView: true,
                  InitiateCheckout: true,
                  Purchase: true,
                  AddToCart: true,
                  ViewContent: true,
                },
              }],
            },
            paymentSetupConfig: {
              card: { enabled: true, method: 'card', provider: 'tagada', paymentFlowId: 'flow_xxx' },
            },
            scripts: [
              {
                name: 'Checkout analytics',
                enabled: true,
                content: `console.log('Checkout step loaded');`,
                position: 'body-end',
              },
            ],
          },
        },
      },
      {
        id: 'step-thankyou',
        name: 'Thank You',
        type: 'thankyou',
        position: { x: 600, y: 0 },
        config: {
          pluginId, instanceId,
          pagePath: '/thankyou', path: '/thankyou',
          stepConfig: {
            pixels: {
              ...metaPixel({ Purchase: true }),
              ...tiktokPixel({ Purchase: true }),
            },
          },
        },
      },
    ],
    edges: [
      { id: 'e1', source: 'step-landing', target: 'step-checkout' },
      { id: 'e2', source: 'step-checkout', target: 'step-thankyou' },
    ],
  },
  isDefault: true,
});

// Activate routing
await tagada.funnels.update(funnel.id, {
  storeId,
  config: funnel.config,
});

console.log('Funnel created with per-step tracking!');

Pixel Event Reference

EventWhen it firesTypical steps
PageViewPage loadsAll steps
InitiateCheckoutCustomer starts checkoutCheckout
PurchasePayment succeedsCheckout, Thank You
AddToCartItem added to cartLanding, Checkout
ViewContentProduct/offer viewedLanding, Offer
SearchCustomer searches (Snapchat only)Landing
AddToWishlistWishlist action (Snapchat only)Landing
CompleteRegistrationSign-up (Snapchat only)Thank You

Supported Providers

Provider KeyPixel TypeConfig Fields
facebookMeta Pixel (client-side)pixelId, events
metaConversionMeta Conversion API (server-side)pixelId, accessToken, publishPurchaseIfNewCustomerOnly
tiktokTikTok PixelpixelId, events
snapchatSnap PixelpixelId, events (extended)
gtmGoogle Tag ManagercontainerId, events, googleAdsConversionId, googleAdsConversionLabel
You can attach multiple pixels of the same provider to a single step. For example, two Facebook pixels for different ad accounts — just add more entries to the array.

Payment Setup Config

paymentSetupConfig controls which payment methods are displayed on a checkout step and how each method is routed. It’s a key-value map where keys are method identifiers.

Structure

stepConfig: {
  paymentSetupConfig: {
    card: {
      enabled: true,
      method: 'card',
      provider: 'tagada',
      paymentFlowId: 'flow_xxx',
    },
    'apple_pay:stripe': {
      enabled: true,
      method: 'apple_pay',
      provider: 'stripe',
      express: true,
      processorId: 'processor_xxx',
    },
    'google_pay:stripe': {
      enabled: true,
      method: 'google_pay',
      provider: 'stripe',
      express: true,
      processorId: 'processor_xxx',
    },
    'klarna:airwallex': {
      enabled: false,
      method: 'klarna',
      provider: 'airwallex',
      processorId: 'processor_yyy',
    },
  },
}

Fields

FieldTypeDescription
enabledbooleanWhether this payment method is shown at checkout
methodstringPayment method: card, apple_pay, google_pay, paypal, klarna, ideal, etc.
providerstringProcessor family: tagada, stripe, airwallex, etc.
expressbooleanRender as an express checkout button above the form
paymentFlowIdstringRoute this method through a specific payment flow (cascade, weighted, etc.)
processorIdstringRoute directly to a specific processor (for APMs and express methods)
integrationIdstringTagadaPay native integration ID (for Apple Pay via Basis Theory, etc.)

Key Format

Keys follow the pattern {method} or {method}:{provider}:
  • card — card payments (routed via payment flow)
  • apple_pay:stripe — Apple Pay via Stripe
  • google_pay:stripe — Google Pay via Stripe
  • klarna:airwallex — Klarna via Airwallex
  • paypal:airwallex — PayPal via Airwallex

Payment Flow Resolution Order

When processing a card payment, the paymentFlowId is resolved in this order:
1. paymentSetupConfig.card.paymentFlowId   ← most specific (recommended)
2. payment.paymentFlowId                   ← per-step fallback (legacy)
3. Store's default payment flow            ← if neither is set
The payment: { paymentFlowId } key is legacy. Use paymentSetupConfig.card.paymentFlowId instead — it’s more explicit and supports per-method routing.

Example: Different Flow for High-Value Orders

stepConfig: {
  paymentSetupConfig: {
    card: {
      enabled: true,
      method: 'card',
      provider: 'tagada',
      paymentFlowId: 'flow_high_value',
    },
  },
}

Example: Cards + Apple Pay + Google Pay

stepConfig: {
  paymentSetupConfig: {
    card: {
      enabled: true,
      method: 'card',
      provider: 'tagada',
      paymentFlowId: 'flow_default',
    },
    'apple_pay:stripe': {
      enabled: true,
      method: 'apple_pay',
      provider: 'stripe',
      express: true,
      processorId: 'processor_stripe_us',
    },
    'google_pay:stripe': {
      enabled: true,
      method: 'google_pay',
      provider: 'stripe',
      express: true,
      processorId: 'processor_stripe_us',
    },
  },
}

Next Steps

Node SDK Quick Start

Get started with the Node SDK

Funnel Orchestrator

Deep dive into funnel routing, A/B testing, and navigation

Headless Payments (Frontend)

Build your own checkout UI with client-side card tokenization and 3DS

Deploy & A/B Test

Deploy pages and run split tests