---
title: "How to Track React Sites"
description: "Complete guide to tracking React applications with Sealmetrics. Includes examples for react-router, conversions, and microconversions."
canonical_url: "https://docs.sealmetrics.com/implementation/tracking-methods/how-to-track-react"
lang: "en"
date_generated: "2026-08-27T14:18:06.639Z"
source_hash: "64ed15811b7838daac1a9140f96e166627574dc3d9744f58f8b57def7d05e5d1"
content_type: "implementation"
owner: "engineering"
llm_priority: "critical"
source_file: "implementation/tracking-methods/how-to-track-react.mdx"
publisher: "Sealmetrics"
---

# How to Track React Sites

Canonical page: https://docs.sealmetrics.com/implementation/tracking-methods/how-to-track-react

Sealmetrics works seamlessly with React applications. The tracker automatically detects navigation via react-router and tracks pageviews without additional configuration.

---

## Installation

Add the tracker script to your `index.html` or use React's Script handling:

### Option 1: In public/index.html

```html
<!DOCTYPE html>
<html>
<head>
  <title>My React App</title>
  <!-- Sealmetrics Tracker -->
  <script src="https://t.sealmetrics.com/t.js?id=YOUR_ACCOUNT_ID" defer></script>
</head>
<body>
  <div id="root"></div>
</body>
</html>
```

### Option 2: Using React Helmet

```jsx
import { Helmet } from 'react-helmet';

function App() {
  return (
    <>
      <Helmet>
        <script
          src="https://t.sealmetrics.com/t.js?id=YOUR_ACCOUNT_ID"
          defer
        />
      </Helmet>
      {/* Your app content */}
    </>
  );
}
```

---

## Automatic Pageview Tracking

Once installed, the tracker automatically tracks:

- Initial page load
- Navigation via `react-router` (both v5 and v6)
- Browser back/forward navigation
- Any History API-based routing

**No additional setup required** for basic pageview tracking.

---

## Tracking Conversions

Track purchases, signups, and other goal completions:

```jsx
import { useEffect } from 'react';

function ThankYouPage({ order }) {
  useEffect(() => {
    // Track conversion after component mounts
    if (typeof sealmetrics !== 'undefined') {
      sealmetrics.conv('purchase', order.total, {
        currency: order.currency,
        payment_method: order.paymentMethod
      });
    }
  }, [order]);

  return (
    <div>
      <h1>Thank you for your purchase!</h1>
      <p>Order #{order.id}</p>
    </div>
  );
}
```

---

## Tracking Microconversions

Track user interactions and funnel steps:

### Add to Cart

```jsx
function ProductPage({ product }) {
  const handleAddToCart = () => {
    // Your cart logic...

    if (typeof sealmetrics !== 'undefined') {
      sealmetrics.micro('add_to_cart', {
        product_id: product.id,
        product_name: product.name,
        price: String(product.price),
        category: product.category
      });
    }
  };

  return (
    <div>
      <h1>{product.name}</h1>
      <button onClick={handleAddToCart}>Add to Cart</button>
    </div>
  );
}
```

### Form Submission

```jsx
function ContactForm() {
  const handleSubmit = (e) => {
    e.preventDefault();

    // Your form submission logic...

    if (typeof sealmetrics !== 'undefined') {
      sealmetrics.micro('form_submit', {
        form_name: 'contact',
        form_location: 'footer'
      });
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* Form fields */}
      <button type="submit">Send</button>
    </form>
  );
}
```

---

## Custom Hook for Analytics

Create a reusable hook for cleaner code:

```jsx
// hooks/useAnalytics.js
export function useAnalytics() {
  const trackConversion = (type, amount, properties = {}) => {
    if (typeof sealmetrics !== 'undefined') {
      sealmetrics.conv(type, amount, properties);
    }
  };

  const trackMicro = (type, properties = {}) => {
    if (typeof sealmetrics !== 'undefined') {
      sealmetrics.micro(type, properties);
    }
  };

  const trackPageview = (options = {}) => {
    if (typeof sealmetrics !== 'undefined') {
      sealmetrics(options);
    }
  };

  return { trackConversion, trackMicro, trackPageview };
}
```

**Usage:**

```jsx
import { useAnalytics } from './hooks/useAnalytics';

function CheckoutSuccess({ order }) {
  const { trackConversion } = useAnalytics();

  useEffect(() => {
    trackConversion('purchase', order.total, {
      currency: order.currency
    });
  }, [order]);

  return <div>Thank you!</div>;
}
```

---

## TypeScript Support

Add type declarations for better IDE support:

```typescript
// types/sealmetrics.d.ts
interface SealmetricsOptions {
  group?: string;
}

interface SealmetricsFunction {
  (options?: SealmetricsOptions): void;
  conv(type: string, amount: number, properties?: Record<string, string>): void;
  micro(type: string, properties?: Record<string, string>): void;
}

declare global {
  const sealmetrics: SealmetricsFunction | undefined;
  const sm: SealmetricsFunction | undefined;
  const _sm: SealmetricsFunction | undefined;
}

export {};
```

**Typed hook:**

```typescript
// hooks/useAnalytics.ts
export function useAnalytics() {
  const trackConversion = (
    type: string,
    amount: number,
    properties?: Record<string, string>
  ) => {
    if (typeof sealmetrics !== 'undefined') {
      sealmetrics.conv(type, amount, properties);
    }
  };

  const trackMicro = (type: string, properties?: Record<string, string>) => {
    if (typeof sealmetrics !== 'undefined') {
      sealmetrics.micro(type, properties);
    }
  };

  return { trackConversion, trackMicro };
}
```

---

## Content Grouping

Group pages by content type for better analytics:

```jsx
function BlogPost({ post }) {
  useEffect(() => {
    // Set content group for this page
    if (typeof sealmetrics !== 'undefined') {
      sealmetrics({ group: 'blog' });
    }
  }, [post.slug]);

  return <article>{/* Post content */}</article>;
}
```

Or use different tracker URLs per page type:

```jsx
// For blog section
<Helmet>
  <script
    src="https://t.sealmetrics.com/t.js?id=YOUR_ACCOUNT_ID&group=blog"
    defer
  />
</Helmet>
```

---

## React Router Integration

### With react-router v6

The tracker works automatically with react-router v6:

```jsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/products" element={<Products />} />
        <Route path="/products/:id" element={<ProductDetail />} />
        <Route path="/checkout" element={<Checkout />} />
        <Route path="/thank-you" element={<ThankYou />} />
      </Routes>
    </BrowserRouter>
  );
}
```

Navigation between routes is tracked automatically.

### With react-router v5

Also works automatically:

```jsx
import { BrowserRouter, Switch, Route } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/products/:id" component={ProductDetail} />
        <Route path="/checkout" component={Checkout} />
      </Switch>
    </BrowserRouter>
  );
}
```

---

## E-commerce Example

Complete checkout flow tracking:

```jsx
// Cart page
function CartPage({ cart }) {
  const { trackMicro } = useAnalytics();

  useEffect(() => {
    trackMicro('view_cart', {
      items_count: String(cart.items.length),
      cart_value: String(cart.total)
    });
  }, []);

  return <div>{/* Cart UI */}</div>;
}

// Checkout page
function CheckoutPage({ cart }) {
  const { trackMicro } = useAnalytics();

  useEffect(() => {
    trackMicro('begin_checkout', {
      items_count: String(cart.items.length),
      cart_value: String(cart.total)
    });
  }, []);

  return <div>{/* Checkout form */}</div>;
}

// Thank you page
function ThankYouPage({ order }) {
  const { trackConversion } = useAnalytics();

  useEffect(() => {
    trackConversion('purchase', order.total, {
      currency: order.currency,
      items_count: String(order.items.length)
    });
  }, []);

  return <div>Thank you for your order!</div>;
}
```

---

## Troubleshooting

### Tracker not defined

Always check if the tracker is loaded before using it:

```jsx
if (typeof sealmetrics !== 'undefined') {
  sealmetrics.conv('purchase', 99.99);
}
```

### Duplicate pageviews

- Ensure the tracker script is only included once
- Don't manually call `sealmetrics()` if automatic tracking is sufficient
- Use `useEffect` with proper dependencies to avoid re-triggering

### Events not appearing

1. Check the browser Network tab for requests to `t.sealmetrics.com`
2. Verify your Site ID is correct
3. Check the **Last hit** timestamp on the **Overview** report in your Sealmetrics dashboard — it updates within seconds of a tracked hit; conversions appear in the **Conversions** report

---

## Related Documentation

- [SPA Support](/implementation/tracker/spa-support) - Detailed SPA integration
- [Conversions](/implementation/tracker/conversions) - All conversion tracking options
- [Microconversions](/implementation/tracker/microconversions) - Tracking user interactions
- [Next.js Integration](/integrations/frameworks/nextjs) - For Next.js projects
