Skip to main content
Ask your AI

React Quickstart

This guide shows you how to integrate walkerOS into your React application with automatic pageview tracking and component-level event tracking.

Key concepts​

  • Single file setup: One initialization file, direct usage in App.tsx
  • No providers needed: Direct integration in your main App component
  • StrictMode safe: Handles React's double execution correctly
  • Data attributes: Use the tagger helper for clean component tracking

Installation​

First, install the required walkerOS packages:

npm install @walkeros/core @walkeros/collector @walkeros/web-source-browser

Setup​

1. walker initialization​

// apps/demos/react/src/walker/index.ts
import type { Collector, WalkerOS } from '@walkeros/core';
import { startFlow } from '@walkeros/collector';

import { createTagger, sourceBrowser } from '@walkeros/web-source-browser';

// Global type declarations
declare global {
  interface Window {
    elb: WalkerOS.Elb;
    walker: Collector.Instance;
  }
}

export async function initializeWalker(): Promise<void> {
  // Skip initialization if already done
  if (window.walker) return;

  // Create collector with run: false for manual pageview control
  const { collector } = await startFlow({
    run: false,
    consent: { functional: true },
    sources: {
      browser: {
        code: sourceBrowser,
        config: {
          settings: {
            pageview: true,
            session: true,
            elb: 'elb',
          },
        },
      },
    },
    destinations: {
      console: {
        code: {
          type: 'console',
          config: {},
          push: (event) => console.log('Event:', event.name),
        },
      },
    },
  });

  // Set global window object
  window.walker = collector;
}

// Tagger helper for easy component tagging
const taggerInstance = createTagger();

export function tagger(entity?: string) {
  return taggerInstance(entity);
}

2. App integration​

Integrate directly in your main App component:

// apps/demos/react/src/App.tsx
import { Routes, Route, useLocation } from 'react-router-dom';
import { useEffect, useRef } from 'react';
import { initializeWalker } from './walker';

function App() {
  const location = useLocation();
  const hasInitialized = useRef(false);
  const firstRun = useRef(true);

  useEffect(() => {
    // Prevent React StrictMode double execution
    if (!hasInitialized.current) {
      initializeWalker();
      hasInitialized.current = true;
    }
  }, []);

  useEffect(() => {
    // Skip first run to prevent double page views
    if (firstRun.current) {
      firstRun.current = false;
      return;
    }

    window.elb('walker run');
  }, [location]);

  return (
    <div className="min-h-screen bg-gray-50">
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/category" element={<Category />} />
        <Route path="/product/:id" element={<Detail />} />
      </Routes>
    </div>
  );
}

export default App;

Component tagging​

Use the tagger helper for clean component tracking:

// apps/demos/react/src/components/ProductDetail.tsx
import { tagger } from '../walker';

function ProductDetail({ productId }: { productId: string }) {
  const product = getProductById(parseInt(productId));

  return (
    <div
      {...tagger()
        .entity('product')
        .action('load', 'view')
        .data('productId', productId)
        .get()}
      className="bg-white rounded-lg shadow p-8"
    >
      <h1
        {...tagger('product').data('name', product.name).get()}
        className="text-3xl font-bold mb-2"
      >
        {product.name}
      </h1>

      <p
        {...tagger('product').data('price', product.price).get()}
        className="text-3xl font-bold text-blue-600"
      >
        €{product.price}
      </p>

      <button
        {...tagger().action('click', 'add').get()}
        className="w-full bg-blue-600 text-white py-3 px-6 rounded-lg"
      >
        Add to Cart
      </button>
    </div>
  );
}
// Without tagger helper (verbose)
<div
  data-elb="product"
  data-elb-action="view"
  data-elb-id={product.id}
  data-elb-name={product.name}
  data-elb-price={product.price}
>

  // With tagger helper (clean)
<div
  {...tagger('product')
    .action('view')
    .data('id', product.id)
    .data('name', product.name)
    .data('price', product.price)
    .get()}
>

info

When using the tagger helper, make sure to call .get() at the end of the chain.

Manual event tracking​

Use the elb function for custom events:

function CheckoutForm() {
  const handleSubmit = (formData: any) => {
    window.elb('checkout complete', {
      total: formData.total,
      items: formData.items.length,
    });
  };

  return <form onSubmit={handleSubmit}>{/* Form fields */}</form>;
}

Testing​

During #1-walker-initialization, we added a console destination. This will output events to the console. Open your browser's developer console to see tracked events:

Event: "product view", { id: 123, name: "Premium Chocolate", price: 12.99 }

Best practices​

  1. Use tagger: Clean component tagging with the tagger helper
  2. Minimal React code: Keep React integration as simple as possible
  3. Trust walkerOS: No need for custom error handling or state management
  4. Direct integration: No providers needed, integrate directly in App component
  5. Test with console: Use console destination during development

Troubleshooting​

Events not firing​

  1. Check that window.walker is set in the browser console
  2. Verify data attributes are correctly formatted (use data-elb prefix)
  3. Ensure walker initialization completed (window.walker.allowed must be true)
  4. Check browser console for any error messages

Route changes not tracked​

  1. Check that walker run is called on route changes in window.elbLayer
  2. Ensure firstRun logic is preventing double execution on initial load
  3. Verify location/pathname dependency is working correctly

Next steps​

💡 Setting this up for production?
If your setup involves consent management, server-side pipelines, or custom destinations, the creators of walkerOS offer hands-on implementation support. Start with a free scoping call.