The Umami Analytics Loader is a lightweight script that enables you to easily integrate Umami Analytics into your website. Umami is a simple, open-source website analytics tool that provides valuable insights into your website's traffic without compromisi
npm install @danielgtmn/umami-reactA lightweight, privacy-focused React component for integrating Umami Analytics into your website. Umami is an open-source, privacy-friendly alternative to Google Analytics that helps you understand your website's traffic without compromising user privacy.
- 🚀 Easy integration with props or environment variables
- 🔒 Privacy-focused analytics
- ⚡ Lazy loading support
- 🐛 Debug mode for development
- 📦 Zero runtime dependencies
- 🔍 Full TypeScript support
- 🎯 Custom event tracking hook
- 📊 Manual pageview tracking with UTM support
- 🔄 Async UTM parameter fetching
- 🌐 Custom domain support
- ⚙️ Configurable script attributes
- ⚛️ React 18 & 19 Support - Compatible with both React 18.2+ and React 19
- React: 18.2+ or 19.0+
- Node.js: 16.0+
The package is available on both NPM and GitHub Packages:
bash
pnpm add @danielgtmn/umami-react
`$3
`bash
First, configure npm to use GitHub Packages for @danielgtmn scope
echo "@danielgtmn:registry=https://npm.pkg.github.com" >> .npmrcThen install
pnpm add @danielgtmn/umami-react
`Quick Start
$3
`tsx
import UmamiAnalytics from '@danielgtmn/umami-react';function App() {
return (
url="https://analytics.example.com"
websiteId="your-website-id"
/>
{/ Your app content /}
);
}
`$3
Create a
.env file:`env
UMAMI_URL=https://analytics.example.com
UMAMI_ID=your-website-id
UMAMI_DEBUG=false
UMAMI_LAZY_LOAD=true
`Then use the component:
`tsx
import UmamiAnalytics from '@danielgtmn/umami-react';function App() {
return (
{/ Your app content /}
);
}
`Configuration
$3
| Prop | Type | Description | Default |
|------|------|-------------|---------|
|
url | string | Your Umami instance URL | UMAMI_URL env var |
| websiteId | string | Your website tracking ID | UMAMI_ID env var |
| debug | boolean | Enable debug logging | false |
| lazyLoad | boolean | Enable lazy loading | false |
| onlyInProduction | boolean | Only load in production | true |
| domains | string[] | Custom domains for tracking | undefined |
| scriptAttributes | Record | Additional script attributes | undefined |$3
| Variable | Type | Description | Default |
|----------|------|-------------|---------|
|
UMAMI_URL | string | Your Umami instance URL | "" |
| UMAMI_ID | string | Your website tracking ID | "" |
| UMAMI_DEBUG | string | Enable debug logging | "false" |
| UMAMI_LAZY_LOAD | string | Enable lazy loading | "false" |Advanced Usage
$3
Enable lazy loading to improve initial page load performance:
`tsx
url="https://analytics.example.com"
websiteId="your-website-id"
lazyLoad={true}
/>
`$3
Enable debug mode for development:
`tsx
url="https://analytics.example.com"
websiteId="your-website-id"
debug={true}
/>
`$3
Track only specific domains:
`tsx
url="https://analytics.example.com"
websiteId="your-website-id"
domains={['example.com', 'app.example.com']}
/>
`$3
Add custom attributes to the script tag:
`tsx
url="https://analytics.example.com"
websiteId="your-website-id"
scriptAttributes={{
'data-cache': 'true',
'data-host-url': 'https://custom-host.com'
}}
/>
`Event Tracking
Use the
useUmami hook for custom event tracking:`tsx
import { useUmami } from '@danielgtmn/umami-react';function MyComponent() {
const { track } = useUmami();
const handleClick = () => {
track('button-click', { button: 'header-cta' });
};
return (
);
}
`Manual Pageview Tracking
The
useUmami hook provides comprehensive pageview tracking capabilities, perfect for scenarios where you need to disable auto-tracking and manually control pageview events with custom UTM parameters.> Note: This library correctly integrates with Umami's official tracking API. Pageviews are tracked using Umami's standard
umami.track() method without custom event names.$3
`tsx
import { useUmami } from '@danielgtmn/umami-react';function MyComponent() {
const { trackPageview } = useUmami();
const handlePageview = () => {
trackPageview({
url: '/custom-page',
title: 'Custom Page Title',
referrer: document.referrer,
});
};
return (
);
}
`$3
`tsx
import { useUmami } from '@danielgtmn/umami-react';function MyComponent() {
const { trackPageviewWithUTM } = useUmami();
const handleUTMPageview = () => {
trackPageviewWithUTM({
utm_source: 'newsletter',
utm_medium: 'email',
utm_campaign: 'spring-sale',
utm_term: 'discount',
utm_content: 'header-link',
});
};
return (
);
}
`$3
For scenarios where you need to fetch UTM parameters from your backend using a unique ID:
`tsx
import { useUmami, UTMFetcher } from '@danielgtmn/umami-react';function MyComponent() {
const { trackPageviewAsync } = useUmami();
// Define your UTM fetcher function
const fetchUTMData: UTMFetcher = async (utmId: string) => {
const response = await fetch(
/api/utm/${utmId});
const data = await response.json();
return {
utm_source: data.source,
utm_medium: data.medium,
utm_campaign: data.campaign,
utm_term: data.term,
utm_content: data.content,
};
}; const handleAsyncPageview = async () => {
// This will fetch UTM data from your backend and track the pageview
await trackPageviewAsync('unique-utm-id-123', fetchUTMData, {
// Optional additional data
custom_property: 'custom_value',
});
};
return (
);
}
`$3
Assign a unique ID to the current session for user tracking:
`tsx
import { useUmami } from '@danielgtmn/umami-react';function MyComponent() {
const { identify } = useUmami();
const handleLogin = (userId: string) => {
// Assign the user ID to the current session
identify(userId);
};
return (
);
}
`$3
The
useUmami hook provides the following methods:`tsx
const {
track, // Original event tracking
trackPageview, // Manual pageview tracking
trackPageviewWithUTM, // Pageview with UTM parameters
trackPageviewAsync, // Async UTM fetching + pageview
identify // Assign unique ID to session
} = useUmami();
`$3
`tsx
import { PageviewData, UTMFetcher } from '@danielgtmn/umami-react';// PageviewData interface
const pageviewData: PageviewData = {
url: '/custom-page',
title: 'Page Title',
referrer: 'https://example.com',
utm_source: 'google',
utm_medium: 'cpc',
utm_campaign: 'summer-sale',
utm_term: 'shoes',
utm_content: 'ad-1',
utm_id: 'unique-id-123',
// Any additional custom properties
custom_field: 'custom_value',
};
// UTMFetcher function type
const myUTMFetcher: UTMFetcher = async (utmId: string) => {
// Your implementation
return {
utm_source: 'backend-source',
utm_medium: 'backend-medium',
// ... other UTM parameters
};
};
`$3
When using manual pageview tracking, you might want to disable Umami's automatic pageview tracking by adding the
data-auto-track="false" attribute:`tsx
url="https://analytics.example.com"
websiteId="your-website-id"
scriptAttributes={{
'data-auto-track': 'false'
}}
/>
`$3
The async UTM fetching includes built-in error handling. If the UTM fetcher fails, it will:
1. Log an error to the console (in debug mode)
2. Fall back to basic pageview tracking with the provided
utm_id
3. Include any additional data you provided`tsx
// This will gracefully handle network errors
await trackPageviewAsync('utm-id', failingFetcher, {
fallback_source: 'direct',
});
`TypeScript Support
The package includes full TypeScript support with exported interfaces:
`tsx
import UmamiAnalytics, { UmamiAnalyticsProps, UmamiConfig } from '@danielgtmn/umami-react';const config: UmamiAnalyticsProps = {
url: 'https://analytics.example.com',
websiteId: 'your-website-id',
debug: true,
lazyLoad: true,
};
`Framework Integration
$3
`tsx
// pages/_app.tsx or app/layout.tsx
import UmamiAnalytics from '@danielgtmn/umami-react';export default function App({ Component, pageProps }) {
return (
<>
url="https://analytics.example.com"
websiteId="your-website-id"
/>
>
);
}
`$3
`tsx
// src/App.tsx
import UmamiAnalytics from '@danielgtmn/umami-react';function App() {
return (
url="https://analytics.example.com"
websiteId="your-website-id"
/>
{/ Your app content /}
);
}
`Development
`bash
Install dependencies
pnpm installStart development mode
pnpm devRun linting
pnpm lintAuto-fix linting issues
pnpm lint:fixFormat code
pnpm formatType check
pnpm type-checkRun tests
pnpm testRun tests once
pnpm test:runRun tests with coverage
pnpm test:coverageRun tests in watch mode
pnpm test:watchCheck bundle size
pnpm sizeAnalyze bundle
pnpm analyzeBuild for production
pnpm buildClean build artifacts
pnpm clean
`Development Workflow
This project uses modern development tools to ensure code quality:
$3
Git hooks automatically run quality checks before commits:
- Pre-commit: TypeScript check, linting, and tests
- Commit-msg: Validates commit message format$3
Commits follow Conventional Commits format:`bash
type(scope): descriptionExamples:
feat: add new tracking feature
fix: resolve lazy loading bug
docs: update README
test: add component tests
`Allowed types:
build, chore, ci, docs, feat, fix, perf, refactor, revert, style, testTesting
This project uses Vitest for testing with React Testing Library.
`bash
Run tests
pnpm testRun tests with coverage
pnpm test:coverageRun tests in watch mode
pnpm test:watch
`CI/CD
This project uses GitHub Actions for continuous integration and deployment:
- CI Pipeline (
.github/workflows/ci.yml): Runs on every push/PR to main
- Tests across multiple Node.js versions (18.x, 20.x, 22.x)
- Linting and type checking
- Bundle size monitoring
- Test coverage reporting- Release Pipeline (
.github/workflows/publish.yml): Runs on releases
- Runs full test suite before publishing
- Publishes to NPM with public accessBundle Analysis
The project includes bundle size monitoring and analysis:
`bash
Check current bundle sizes
pnpm sizeAnalyze bundle composition
pnpm analyze
`Bundle size limits:
- ESM: ≤ 3 KB (gzipped)
- CJS: ≤ 3.5 KB (gzipped)
Contributing
Contributions are welcome! Please ensure:
1. Follow commit conventions: Use Conventional Commits format
2. Quality checks: Git hooks automatically run:
- TypeScript type checking
- ESLint linting
- Test execution
- Commit message validation
3. Manual verification:
- All tests pass:
pnpm test:run
- Code is linted: pnpm lint
- Bundle size is within limits: pnpm size
- TypeScript types are correct: pnpm type-check$3
`bash
Install dependencies
pnpm installGit hooks are automatically set up via prepare script
If needed manually: pnpm prepare
``Please feel free to submit a Pull Request!