An official plugin to add the Hardal tracking to your web project with automatic pageview tracking, click tracking, and privacy-first analytics.
Hardal is a privacy-first, server-side analytics platform that helps you:
- Track user behavior without compromising privacy
- Automatic PII redaction from URLs and data
- First-party data collection - you own your data
- Event tracking with custom properties
- Automatic pageview tracking for SPAs and Next.js
- Works everywhere - Vanilla JS, React, Next.js, Vue, etc.
npm install hardal
# or
bun add hardal
# or
yarn add hardal// app/providers.tsx
'use client';
import { HardalProvider } from 'hardal/react';
export function Providers({ children }: { children: React.ReactNode }) {
return (
<HardalProvider
config={{
website: // Your Hardal Signal ID,
hostUrl: // Your Hardal Signal Domain,
}}
autoPageTracking={true} // β
Tracks all route changes
>
{children}
</HardalProvider>
);
}<script
defer
src="<YOUR_SIGNAL_ENDPOINT>/hardal"
data-website-id="<YOUR_SIGNAL_ID>"
data-host-url="<YOUR_SIGNAL_ENDPOINT>"
data-auto-track="true"
></script>'use client';
import { useHardal } from 'hardal/react';
export function ContactForm() {
const { track, distinct } = useHardal();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
const email = formData.get('email') as string;
// Track the submission
await track('form_submitted', {
formType: 'contact',
source: 'landing_page',
});
// Identify the user
await distinct({
email,
source: 'contact_form',
});
};
return <form onSubmit={handleSubmit}>{/* form fields */}</form>;
}<HardalProvider
config={{
website: 'your-website-id', // Required: Your Hardal website ID
hostUrl: 'https://your-host.com', // Required: Your Hardal server URL
}}
autoPageTracking={true} // Optional: Auto-track route changes (default: false)
disabled={process.env.NODE_ENV === 'development'} // Optional: Disable tracking
>
{children}
</HardalProvider>const hardal = new Hardal({
website: 'your-website-id',
hostUrl: 'https://your-hardal-server.com',
autoTrack: true, // Auto-track pageviews and history changes
});// Identify a user with custom properties
hardal?.distinct({
userId: 'user-123',
email: 'user@example.com',
plan: 'premium',
});// Track a pageview manually
hardal?.trackPageview();Creates a new Hardal instance.
Config Options:
website(required): Your Hardal website IDhostUrl(optional): Custom host URL for your Hardal serverautoTrack(optional): Auto-track pageviews (default:true)
Track a custom event.
hardal.track('event_name', { custom: 'data' });Identify a user with custom properties.
hardal.distinct({ userId: '123', email: 'user@example.com' });Manually track a pageview.
hardal.trackPageview();const { track, distinct } = useHardal();
// Track which variant user sees
track('experiment_viewed', {
experimentId: 'pricing_test_v1',
variant: 'B',
});
// Associate user with variant
distinct({
experiments: {
pricing_test_v1: 'B',
},
});const { track } = useHardal();
try {
await riskyOperation();
} catch (error) {
track('error_occurred', {
errorType: error.name,
errorMessage: error.message,
page: window.location.pathname,
});
}'use client';
import { useEffect } from 'react';
import { useHardal } from 'hardal/react';
export function TimeTracker() {
const { track } = useHardal();
useEffect(() => {
const startTime = Date.now();
return () => {
const timeSpent = Math.round((Date.now() - startTime) / 1000);
track('time_on_page', {
seconds: timeSpent,
page: window.location.pathname,
});
};
}, [track]);
return null;
}<HardalProvider
config={{
website: // Your Hardal Signal ID,
hostUrl: // Your Hardal Signal Domain,
}}
disabled={process.env.NODE_ENV === 'development'} // Don't track in dev
autoPageTracking={true}
>
{children}
</HardalProvider>β DO:
- Track meaningful user actions (clicks, form submissions, purchases)
- Use descriptive event names (
checkout_completed, notevent1) - Include relevant context in event properties
- Identify users after authentication
- Test tracking in production-like environment
β DON'T:
- Track PII (emails, phone numbers) directly - use
distinct()for user identification - Send sensitive data in properties
- Track too many events (focus on business-critical actions)
- Use autoTrack in React apps - use
autoPageTrackinginstead - Create multiple Hardal instances
Hardal automatically:
- π Redacts PII from URLs (emails, phone numbers, credit cards)
- π‘οΈ Respects Do Not Track when configured
- π Server-side processing - no third-party trackers
- π First-party cookies - you own your data
- β GDPR & CCPA friendly
- π¦ Lightweight: ~18KB minified
- β‘ Non-blocking: Events sent asynchronously
- π Queue system: No lost events during initialization
- β±οΈ 5-second timeout: Requests abort if server is slow
- π§Ή Memory safe: Proper cleanup on unmount
Check the examples/ directory for complete examples:
- Next.js App Router -
examples/nextjs-app-router.tsx - Next.js Pages Router -
examples/nextjs-pages-router.tsx - React SPA -
examples/react-spa.tsx - HTML Data Attributes -
examples/data-attributes.html
- β Don't use
autoTrack: truein the config for React apps - β
Use
autoPageTracking={true}inHardalProviderinstead
- Make sure you've set
hostUrlin your config - Verify it starts with
http://orhttps://
- Check browser console for errors
- Verify
hostUrlandwebsiteID are correct - Make sure your Hardal server is running
- Check network tab for failed requests
- Run
npm installto ensure dependencies are installed - Restart TypeScript server in your IDE
- See TYPESCRIPT_SETUP.md
// β Old way (v2.x)
const hardal = new Hardal({
endpoint: 'https://server.com',
autoPageview: true,
});
// β
New way (v3.x)
<HardalProvider
config={{
website: 'your-id',
hostUrl: 'https://server.com',
}}
autoPageTracking={true}
>Breaking changes:
endpointβhostUrlautoPageviewβ removed (useautoPageTrackingprop instead)fetchFromGA4,fetchFromFBPixel,fetchFromRTB,fetchFromDataLayerβ removed- React: Must use
HardalProviderwrapper
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
- Documentation: https://usehardal.com/docs
- Email: support@usehardal.com