@aranova/tracking-next
v0.7.2
Published
Next.js tracking utilities for Aranova client sites
Downloads
883
Readme
@aranova/tracking-next
Next.js tracking utilities for Aranova client sites. Use this package for App Router installs where attribution cookies should be captured before client JavaScript runs.
Install
npm install @aranova/tracking-nextMiddleware
Install the tracking middleware so gclid, fbclid, and UTM params are written to cookies from the first HTTP response.
// middleware.ts
import { createTrackingMiddleware } from '@aranova/tracking-next/middleware';
export default createTrackingMiddleware();
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};Provider
Create one shared tracking module and use its scoped exports throughout your app.
// lib/tracking.ts
import { createTracking } from '@aranova/tracking-next';
export const { TrackingProvider, useTracking } = createTracking({
apiKey: process.env.NEXT_PUBLIC_ARANOVA_TRACKING_API_KEY!,
endpoint: process.env.NEXT_PUBLIC_ARANOVA_TRACKING_ENDPOINT!,
triggers: {
automatic: {
page_view: {},
time_on_site: { thresholdSeconds: 60 },
specific_page_visit: {
pages: [{ name: 'contact_page', pathPattern: /^\/(contact|book|get-started)/ }],
},
},
manual: {
form_submit: {},
phone_click: {},
cta_click: {},
},
},
debug: process.env.NODE_ENV !== 'production',
});Wrap the root layout.
// app/layout.tsx
import { ConsentBanner, GoogleAdsTracking } from '@aranova/tracking-next';
import { TrackingProvider } from '@/lib/tracking';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
{process.env.NEXT_PUBLIC_GTAG_ID && (
<GoogleAdsTracking gtagId={process.env.NEXT_PUBLIC_GTAG_ID} />
)}
</head>
<body>
<TrackingProvider>
{children}
<ConsentBanner />
</TrackingProvider>
</body>
</html>
);
}Multiple gtag IDs
To install multiple Google Ads tags simultaneously (for example a production MCC and a test MCC for verifying conversion actions before they touch the live account), pass gtagIds instead of gtagId. Every entry fires gtag('config', ...) on every page — gtag natively supports multiple configured tags.
<GoogleAdsTracking
gtagIds={{
production: 'AW-111111111', // real client account
test: 'AW-222222222', // test MCC for development
}}
/>The labels are arbitrary and surface in the Aranova dashboard's SDK versions table. Also pass environment to the factory so events are tagged with the deployment context for dashboard filtering:
// lib/tracking.ts
createTracking({
apiKey: process.env.NEXT_PUBLIC_ARANOVA_TRACKING_API_KEY!,
endpoint: process.env.NEXT_PUBLIC_ARANOVA_TRACKING_ENDPOINT!,
environment: process.env.NEXT_PUBLIC_TRACKING_ENVIRONMENT, // 'production' | 'development'
gtagIds: { // optional — reports the configured tags in heartbeat metadata
production: process.env.NEXT_PUBLIC_GTAG_PROD!,
test: process.env.NEXT_PUBLIC_GTAG_TEST!,
},
triggers: { /* ... */ },
});Manual Events
Import useTracking from your local lib/tracking module, not directly from the package.
'use client';
import { useTracking } from '@/lib/tracking';
export function LeadForm() {
const tracking = useTracking();
return (
<form
id="lead-form"
action="/api/lead"
onSubmit={(event) => {
const form = event.currentTarget;
const data = new FormData(form);
tracking.trackEvent('form_submit', {
form: {
id: form.id,
action: form.getAttribute('action'),
fields: [
{
name: 'service_interest',
type: 'select',
label: 'Service interest',
value: String(data.get('service_interest') ?? ''),
},
{
name: 'is_existing_patient',
type: 'checkbox',
label: 'Existing patient',
value: data.get('is_existing_patient') === 'on',
},
],
},
page: { path: window.location.pathname },
});
}}
>
{/* fields */}
</form>
);
}fields[].value can be any JSON value: string, number, boolean, null, array, or object. Only send reviewed, allowlisted, non-sensitive values; do not send names, emails, phone numbers entered by the visitor, addresses, payment data, medical details, passwords, file contents, or free-text messages.
Server Reads
Read attribution cookies from Server Components or server actions.
import { getTrackingParamsServer } from '@aranova/tracking-next/server';
export default function Page() {
const { gclid, utm_source } = getTrackingParamsServer();
return gclid || utm_source === 'google' ? <GoogleLanding /> : <OrganicLanding />;
}Exports
- Root package:
createTracking,TrackingProvider,useTracking,GoogleAdsTracking,ConsentBanner, hooks, and event types @aranova/tracking-next/middleware:createTrackingMiddleware()@aranova/tracking-next/server:getTrackingParamsServer()
