Examples
These examples assume GoogleAnalytics is already mounted in your app's root layout. Call useGoogleAnalytics() inside a React component or custom hook.
Track a successful signup
Send conversion events after the operation succeeds. Use your application's opaque user ID for association; avoid sending email addresses or other identifying form fields.
import { useGoogleAnalytics } from 'tanstack-router-ga4';
type SignupButtonProps = {
register: () => Promise<{ id: string }>;
};
export function SignupButton({ register }: SignupButtonProps) {
const ga = useGoogleAnalytics();
async function handleSignup() {
const user = await register();
ga.set({ user_id: user.id });
ga.event('sign_up', { method: 'email' });
}
return <button onClick={handleSignup}>Create account</button>;
}
Clear the association when your app signs the user out:
ga.set({ user_id: null });
Measure a lead or custom action
ga.event('generate_lead', {
currency: 'USD',
value: 50,
lead_source: 'pricing-page',
});
ga.event('example_copied', {
example_name: 'root-layout',
language: 'tsx',
});
The event wrapper provides parameter types for exception, generate_lead, login, page_view, search, select_content, share, and sign_up. Other event names accept custom payloads. The general string overload also accepts arbitrary events, so TypeScript is a convenience rather than a complete validator of GA4 event semantics.
Track search without treating it as navigation
Automatic page views depend on the pathname. Record a search explicitly when a query-string update or in-page interaction represents a meaningful search:
ga.event('search', { search_term: 'route analytics' });
Set shared or per-stream configuration
ga.set({
user_properties: { account_tier: 'team' },
});
ga.config('G-XXXXXXXXXX', {
content_group: 'guides',
send_page_view: false,
});
set sends global parameters; config targets a measurement ID. When configuring the stream directly, keep send_page_view: false if you want the mounted component to remain responsible for page views. The component sets that option automatically during its own initialization.
Read the client ID
get uses a callback, not a returned promise:
import { useState } from 'react';
import { useGoogleAnalytics } from 'tanstack-router-ga4';
export function ClientIdButton() {
const ga = useGoogleAnalytics();
const [clientId, setClientId] = useState<string>();
return (
<>
<button
onClick={() => {
ga.get('G-XXXXXXXXXX', 'client_id', (value) => {
setClientId(value);
});
}}
>
Read client ID
</button>
<output>{clientId ?? 'No client ID available'}</output>
</>
);
}
Supported field names are campaign_name, client_id, gclid, and session_id. The callback depends on Google's script processing the command. A blocked script, unavailable network, or consent configuration can affect availability; do not make application functionality depend on receiving a callback.
For consent defaults and updates, see Behavior and consent.