Skip to content

Next.js Integration

Integrate usertrax with your Next.js application to track conversions and user interactions.

  1. Add Script Tag to Head

    Add the usertrax script tag to your HTML head section:

    For Pages Router - Update pages/_document.js:

    pages/_document.js
    import { Html, Head, Main, NextScript } from "next/document";
    export default function Document() {
    return (
    <Html lang="en">
    <Head>
    <script
    src="https://usertrax.io/cvs.js"
    data-key={process.env.NEXT_PUBLIC_USERTRAX_KEY}
    async
    />
    </Head>
    <body>
    <Main />
    <NextScript />
    </body>
    </Html>
    );
    }

    For App Router - Update app/layout.js:

    app/layout.js
    export default function RootLayout({ children }) {
    return (
    <html lang="en">
    <head>
    <script
    src="https://usertrax.io/cvs.js"
    data-key={process.env.NEXT_PUBLIC_USERTRAX_KEY}
    async
    />
    </head>
    <body>{children}</body>
    </html>
    );
    }
  2. Create Helper Functions

    Create a new file lib/usertrax.js in your project:

    lib/usertrax.js
    // Helper functions for common events
    export const trackConversion = (data) => {
    if (window.usertrax) {
    window.usertrax.push(data);
    } else {
    console.warn("Usertrax not loaded yet");
    }
    };
    export const trackPageView = (page) => {
    if (window.usertrax) {
    window.usertrax.push({
    event: "page_view",
    page: page,
    });
    } else {
    console.warn("Usertrax not loaded yet");
    }
    };
    export const trackEvent = (eventName, data = {}) => {
    if (window.usertrax) {
    window.usertrax.push({
    event: eventName,
    ...data,
    });
    } else {
    console.warn("Usertrax not loaded yet");
    }
    };
  3. Add Environment Variables

    Create or update your .env.local file:

    NEXT_PUBLIC_USERTRAX_KEY=your_public_key_here
  4. Setup Page View Tracking

    For Pages Router - Update pages/_app.js:

    // pages/_app.js (Pages Router)
    import { useEffect } from "react";
    import { useRouter } from "next/router";
    import { trackPageView } from "../lib/usertrax";
    function MyApp({ Component, pageProps }) {
    const router = useRouter();
    useEffect(() => {
    // Track page views
    const handleRouteChange = (url) => {
    trackPageView(url);
    };
    router.events.on("routeChangeComplete", handleRouteChange);
    return () => {
    router.events.off("routeChangeComplete", handleRouteChange);
    };
    }, [router]);
    return <Component {...pageProps} />;
    }
    export default MyApp;

    For App Router - Create app/components/PageTracker.jsx:

    app/components/PageTracker.jsx
    "use client";
    import { useEffect } from "react";
    import { usePathname } from "next/navigation";
    import { trackPageView } from "../../lib/usertrax";
    export default function PageTracker() {
    const pathname = usePathname();
    useEffect(() => {
    // Track page views
    trackPageView(pathname);
    }, [pathname]);
    return null;
    }

    Then add it to your app/layout.js:

    app/layout.js
    import PageTracker from "./components/PageTracker";
    export default function RootLayout({ children }) {
    return (
    <html lang="en">
    <head>
    <script
    src="https://usertrax.io/cvs.js"
    data-key={process.env.NEXT_PUBLIC_USERTRAX_KEY}
    async
    />
    </head>
    <body>
    <PageTracker />
    {children}
    </body>
    </html>
    );
    }
  5. Create Custom Hook

    Create a custom hook for easier tracking in components:

    hooks/useUsertrax.js
    import { useCallback } from "react";
    import { trackConversion, trackEvent } from "../lib/usertrax";
    export const useUsertrax = () => {
    const trackConversionEvent = useCallback((data) => {
    trackConversion(data);
    }, []);
    const trackCustomEvent = useCallback((eventName, data = {}) => {
    trackEvent(eventName, data);
    }, []);
    const trackFormSubmission = useCallback((formData) => {
    trackEvent("form_submitted", formData);
    }, []);
    const trackButtonClick = useCallback((buttonData) => {
    trackEvent("button_clicked", buttonData);
    }, []);
    return {
    trackConversion: trackConversionEvent,
    trackEvent: trackCustomEvent,
    trackFormSubmission,
    trackButtonClick,
    };
    };
components/CheckoutForm.jsx
import { useUsertrax } from "../hooks/useUsertrax";
export default function CheckoutForm() {
const { trackConversion } = useUsertrax();
const handlePurchase = async (orderData) => {
try {
// Process purchase
const response = await fetch("/api/checkout", {
method: "POST",
body: JSON.stringify(orderData),
});
if (response.ok) {
// Track conversion
trackConversion({
event: "purchase",
id: orderData.orderId,
total: orderData.total,
currency: "EUR",
user_data: {
email: orderData.email,
firstname: orderData.firstName,
lastname: orderData.lastName,
},
metadata: {
products: orderData.items,
payment_method: orderData.paymentMethod,
},
});
}
} catch (error) {
console.error("Checkout error:", error);
}
};
return <form onSubmit={handlePurchase}>{/* Form fields */}</form>;
}
components/ContactForm.jsx
import { useUsertrax } from "../hooks/useUsertrax";
export default function ContactForm() {
const { trackFormSubmission } = useUsertrax();
const handleSubmit = async (formData) => {
try {
// Submit form
const response = await fetch("/api/contact", {
method: "POST",
body: JSON.stringify(formData),
});
if (response.ok) {
// Track form submission
trackFormSubmission({
form_type: "contact",
form_data: {
name: formData.name,
email: formData.email,
message_length: formData.message.length,
},
});
}
} catch (error) {
console.error("Form submission error:", error);
}
};
return <form onSubmit={handleSubmit}>{/* Form fields */}</form>;
}
components/CTAButton.jsx
import { useUsertrax } from "../hooks/useUsertrax";
export default function CTAButton({ children, variant, ...props }) {
const { trackButtonClick } = useUsertrax();
const handleClick = (e) => {
trackButtonClick({
button_text: children,
button_variant: variant,
page: window.location.pathname,
});
};
return (
<button onClick={handleClick} {...props}>
{children}
</button>
);
}
lib/usertrax.js
export const trackCustomEvent = (eventName, data = {}) => {
const enhancedData = {
...data,
timestamp: new Date().toISOString(),
user_agent: navigator.userAgent,
referrer: document.referrer,
url: window.location.href,
};
trackEvent(eventName, enhancedData);
};
hooks/useEcommerceTracking.js
import { useUsertrax } from "./useUsertrax";
export const useEcommerceTracking = () => {
const { trackEvent } = useUsertrax();
const trackProductView = (product) => {
trackEvent("product_viewed", {
product_id: product.id,
product_name: product.name,
product_price: product.price,
product_category: product.category,
});
};
const trackAddToCart = (product, quantity = 1) => {
trackEvent("product_added_to_cart", {
product_id: product.id,
product_name: product.name,
product_price: product.price,
quantity: quantity,
});
};
const trackPurchase = (order) => {
trackEvent("purchase", {
order_id: order.id,
total: order.total,
currency: order.currency,
items: order.items,
});
};
return {
trackProductView,
trackAddToCart,
trackPurchase,
};
};
  • Events not being sent: Check browser console for errors and verify API key
  • Environment variables not working: Ensure variables are prefixed with NEXT_PUBLIC_
  • Server-side rendering issues: Use useEffect for client-side initialization
  • TypeScript errors: Add type definitions for the usertrax library
types/usertrax.d.ts
declare global {
interface Window {
usertrax: {
push: (data: any) => void;
};
}
}
export interface UsertraxConfig {
publicKey: string;
scriptUrl?: string;
}
export interface ConversionData {
event: string;
id?: string;
total?: number;
currency?: string;
user_data?: Record<string, any>;
metadata?: Record<string, any>;
}