Quora Ads Data Layer Setup | OpsBlu Docs

Quora Ads Data Layer Setup

Configure data layer structure for Quora Pixel tracking and dynamic event parameters.

Data Layer Overview

A properly structured data layer enables dynamic Quora Pixel event firing with accurate product, conversion, and user data. This is essential for conversion tracking, audience building, and campaign optimization.

Base Data Layer Structure

Initialize Before Pixel

window.quoraDataLayer = window.quoraDataLayer || {
  page: {},
  user: {},
  product: {},
  cart: {},
  transaction: {}
};

Page-Level Data

Set on all pages:

window.quoraDataLayer.page = {
  type: 'homepage', // homepage, product, category, cart, checkout, confirmation
  category: 'widgets',
  url: window.location.href,
  title: document.title
};

E-commerce Data Layer

Product Detail Page

window.quoraDataLayer.product = {
  id: 'SKU_12345',
  name: 'Blue Widget',
  category: 'widgets',
  subcategory: 'blue_widgets',
  price: 49.99,
  currency: 'USD',
  availability: 'in_stock',
  brand: 'WidgetCo'
};

// Fire Quora ViewContent event
qp('track', 'ViewContent', {
  'product_id': window.quoraDataLayer.product.id,
  'value': window.quoraDataLayer.product.price,
  'currency': window.quoraDataLayer.product.currency,
  'category': window.quoraDataLayer.product.category
});

Shopping Cart

window.quoraDataLayer.cart = {
  items: [
    {
      id: 'SKU_12345',
      name: 'Blue Widget',
      price: 49.99,
      quantity: 2,
      category: 'widgets'
    },
    {
      id: 'SKU_67890',
      name: 'Red Widget',
      price: 59.99,
      quantity: 1,
      category: 'widgets'
    }
  ],
  subtotal: 159.97,
  itemCount: 3,
  currency: 'USD'
};

// Fire AddToCart event
function fireQuoraCartEvent(item) {
  qp('track', 'AddToCart', {
    'product_id': item.id,
    'product_name': item.name,
    'value': item.price,
    'currency': 'USD',
    'quantity': item.quantity
  });
}

Purchase / Conversion

window.quoraDataLayer.transaction = {
  id: 'ORDER_12345',
  revenue: 176.97,
  tax: 12.00,
  shipping: 5.00,
  currency: 'USD',
  items: [
    {
      id: 'SKU_12345',
      name: 'Blue Widget',
      category: 'widgets',
      price: 49.99,
      quantity: 2
    },
    {
      id: 'SKU_67890',
      name: 'Red Widget',
      category: 'widgets',
      price: 59.99,
      quantity: 1
    }
  ]
};

// Fire Quora Purchase event
qp('track', 'Purchase', {
  'value': window.quoraDataLayer.transaction.revenue,
  'currency': window.quoraDataLayer.transaction.currency,
  'order_id': window.quoraDataLayer.transaction.id,
  'product_ids': window.quoraDataLayer.transaction.items.map(item => item.id),
  'num_items': window.quoraDataLayer.transaction.items.reduce((sum, item) => sum + item.quantity, 0),
  'shipping': window.quoraDataLayer.transaction.shipping,
  'tax': window.quoraDataLayer.transaction.tax
});

Lead Generation Data Layer

Form Data

window.quoraDataLayer.form = {
  name: 'contact_form',
  type: 'lead_generation',
  location: 'homepage',
  fields: {
    email: '',
    phone: '',
    company: '',
    industry: ''
  }
};

// On form submit
document.getElementById('contact-form').addEventListener('submit', function(e) {
  qp('track', 'GenerateLead', {
    'lead_type': window.quoraDataLayer.form.type,
    'value': '50.00',
    'currency': 'USD',
    'form_name': window.quoraDataLayer.form.name,
    'form_location': window.quoraDataLayer.form.location
  });
});

Registration Data

window.quoraDataLayer.registration = {
  method: 'email', // email, social, sso
  accountType: 'free', // free, premium, enterprise
  referralSource: 'quora_ad'
};

// On registration complete
qp('track', 'CompleteRegistration', {
  'registration_method': window.quoraDataLayer.registration.method,
  'account_type': window.quoraDataLayer.registration.accountType,
  'value': '25.00',
  'referral_source': window.quoraDataLayer.registration.referralSource
});

User Data Layer

User Properties

window.quoraDataLayer.user = {
  id: 'USER_12345',
  email: '', // Hashed for privacy
  status: 'logged_in', // logged_in, logged_out, new
  segment: 'high_value',
  lifetimeValue: 499.95,
  orderCount: 3,
  lastOrderDate: '2024-01-15',
  memberSince: '2023-06-01'
};

Hashed User Data

async function hashUserData(email) {
  const msgBuffer = new TextEncoder().encode(email.toLowerCase().trim());
  const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
  const hashArray = Array.from(new Uint8Array(hashBuffer));
  return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}

// Store hashed email
async function setUserData(email) {
  window.quoraDataLayer.user.emailHash = await hashUserData(email);
}

// Use in events
qp('track', 'Purchase', {
  'value': '99.99',
  'currency': 'USD',
  'order_id': 'ORDER_12345',
  'em': window.quoraDataLayer.user.emailHash
});

Helper Functions

Fire Quora Event from Data Layer

function fireQuoraEventFromDataLayer(eventName, dataLayerPath) {
  const data = getNestedProperty(window.quoraDataLayer, dataLayerPath);

  if (data && typeof qp !== 'undefined') {
    qp('track', eventName, data);
  } else {
    console.error('Quora pixel not loaded or data not found');
  }
}

function getNestedProperty(obj, path) {
  return path.split('.').reduce((current, key) => current?.[key], obj);
}

// Usage
fireQuoraEventFromDataLayer('Purchase', 'transaction');

Build Event Data from Data Layer

function buildQuoraEventData(eventType) {
  let eventData = {};

  switch(eventType) {
    case 'Purchase':
      eventData = {
        value: window.quoraDataLayer.transaction?.revenue,
        currency: window.quoraDataLayer.transaction?.currency || 'USD',
        order_id: window.quoraDataLayer.transaction?.id,
        product_ids: window.quoraDataLayer.transaction?.items?.map(item => item.id),
        num_items: window.quoraDataLayer.transaction?.items?.length || 0
      };
      break;

    case 'AddToCart':
      const lastItem = window.quoraDataLayer.cart?.items?.slice(-1)[0];
      eventData = {
        product_id: lastItem?.id,
        value: lastItem?.price,
        currency: 'USD',
        quantity: lastItem?.quantity
      };
      break;

    case 'GenerateLead':
      eventData = {
        lead_type: window.quoraDataLayer.form?.type,
        value: '50.00',
        currency: 'USD'
      };
      break;
  }

  return eventData;
}

// Usage
const purchaseData = buildQuoraEventData('Purchase');
qp('track', 'Purchase', purchaseData);

GTM Data Layer Integration

Google Tag Manager Data Layer

// Standard GTM data layer push
dataLayer.push({
  'event': 'purchase',
  'ecommerce': {
    'purchase': {
      'actionField': {
        'id': 'ORDER_12345',
        'revenue': '99.99',
        'tax': '8.00',
        'shipping': '5.00'
      },
      'products': [{
        'id': 'SKU_12345',
        'name': 'Blue Widget',
        'price': '49.99',
        'category': 'widgets',
        'quantity': 2
      }]
    }
  }
});

// Sync to Quora data layer
window.quoraDataLayer.transaction = {
  id: dataLayer[dataLayer.length - 1].ecommerce.purchase.actionField.id,
  revenue: parseFloat(dataLayer[dataLayer.length - 1].ecommerce.purchase.actionField.revenue),
  tax: parseFloat(dataLayer[dataLayer.length - 1].ecommerce.purchase.actionField.tax),
  shipping: parseFloat(dataLayer[dataLayer.length - 1].ecommerce.purchase.actionField.shipping),
  currency: 'USD',
  items: dataLayer[dataLayer.length - 1].ecommerce.purchase.products
};

GTM Variables for Quora

Create these Data Layer Variables in GTM:

  • Quora - Product ID: quoraDataLayer.product.id
  • Quora - Product Price: quoraDataLayer.product.price
  • Quora - Transaction Value: quoraDataLayer.transaction.revenue
  • Quora - Transaction ID: quoraDataLayer.transaction.id
  • Quora - Product IDs: Custom JavaScript
function() {
  if (window.quoraDataLayer && window.quoraDataLayer.transaction && window.quoraDataLayer.transaction.items) {
    return window.quoraDataLayer.transaction.items.map(item => item.id);
  }
  return [];
}

Server-Side Data Layer

Node.js Example

const express = require('express');
const app = express();

app.use((req, res, next) => {
  res.locals.quoraDataLayer = {
    page: {
      type: req.path === '/' ? 'homepage' : 'other',
      url: req.protocol + '://' + req.get('host') + req.originalUrl,
      title: 'My Website'
    },
    user: {
      id: req.session?.userId || null,
      status: req.session?.userId ? 'logged_in' : 'logged_out'
    }
  };
  next();
});

app.get('/products/:id', async (req, res) => {
  const product = await getProduct(req.params.id);

  res.locals.quoraDataLayer.product = {
    id: product.sku,
    name: product.name,
    price: product.price,
    category: product.category,
    currency: 'USD'
  };

  res.render('product', {
    product: product,
    quoraDataLayer: res.locals.quoraDataLayer
  });
});

Render in Template

<script>
window.quoraDataLayer = {{{json quoraDataLayer}}};

// Fire Quora event after data layer is set
if (window.quoraDataLayer.product) {
  qp('track', 'ViewContent', {
    'product_id': window.quoraDataLayer.product.id,
    'value': window.quoraDataLayer.product.price,
    'currency': window.quoraDataLayer.product.currency
  });
}
</script>

Testing Data Layer

Console Validation

// Validate data layer structure
function validateQuoraDataLayer() {
  console.log('=== Quora Data Layer Validation ===');

  if (!window.quoraDataLayer) {
    console.error('✗ Data layer not initialized');
    return false;
  }

  console.log('✓ Data layer initialized');
  console.log('Page data:', window.quoraDataLayer.page);
  console.log('User data:', window.quoraDataLayer.user);
  console.log('Product data:', window.quoraDataLayer.product);
  console.log('Transaction data:', window.quoraDataLayer.transaction);

  // Validate required fields for purchase
  if (window.quoraDataLayer.transaction) {
    const required = ['id', 'revenue', 'currency'];
    const missing = required.filter(field => !window.quoraDataLayer.transaction[field]);

    if (missing.length > 0) {
      console.error('✗ Missing required transaction fields:', missing);
      return false;
    }
    console.log('✓ Transaction data valid');
  }

  console.log('===================================');
  return true;
}

// Run validation
validateQuoraDataLayer();

GTM Preview Mode

  1. Enable GTM Preview mode
  2. Navigate through site
  3. Check "Data Layer" tab
  4. Verify quoraDataLayer object
  5. Confirm Quora pixel fires with correct data

Best Practices

  • Initialize data layer before Quora Pixel loads
  • Use consistent naming conventions (camelCase)
  • Validate required fields before firing events
  • Hash sensitive user data (email, phone)
  • Clear data layer between page transitions in SPAs:
// Clear product data on navigation
window.quoraDataLayer.product = {};
  • Document your data layer schema
  • Test data layer in staging before production
  • Use server-side data layer for SSR applications
  • Monitor data quality with validation functions
  • Keep data layer lean - only include necessary data