How to Track React Sites
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
<!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
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:
import { useEffect } from 'react';
function ThankYouPage({ order }) {
useEffect(() => {
// Track conversion after component mounts
if (typeof sealmetrics !== 'undefined') {
sealmetrics.conv('purchase', order.total, {
order_id: order.id,
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
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
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:
// 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:
import { useAnalytics } from './hooks/useAnalytics';
function CheckoutSuccess({ order }) {
const { trackConversion } = useAnalytics();
useEffect(() => {
trackConversion('purchase', order.total, {
order_id: order.id,
currency: order.currency
});
}, [order]);
return <div>Thank you!</div>;
}
TypeScript Support
Add type declarations for better IDE support:
// 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:
// 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:
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:
// 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:
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:
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:
// 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, {
order_id: order.id,
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:
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
useEffectwith proper dependencies to avoid re-triggering
Events not appearing
- Check the browser Network tab for requests to
t.sealmetrics.com - Verify your Account ID is correct
- Check the Real-time report in your SealMetrics dashboard
Related Documentation
- SPA Support - Detailed SPA integration
- Conversions - All conversion tracking options
- Microconversions - Tracking user interactions
- Next.js Integration - For Next.js projects