# Umami Analytics Integration

This project uses [Umami Analytics](https://umami.is/) for privacy-focused website analytics. The implementation is modern, clean, and follows Next.js best practices.

## Overview

The analytics system consists of:

1. **`UmamiScript`** - Loads the Umami tracking script
2. **`AnalyticsProvider`** - Tracks pageviews on route changes
3. **`useAnalytics`** - Custom hook for tracking custom events
4. **`analytics-events.ts`** - Centralized event definitions
5. **`UmamiAnalyticsService`** - Service layer for analytics operations

## Setup

### Environment Variables

Add these to your `.env` file:

```bash
# Required: Your Umami website ID
UMAMI_WEBSITE_ID=59a7db94-0100-4c7e-98ef-99f45b17f9c3

# Optional: Custom Umami script URL (defaults to https://analytics.infra.mintel.me/script.js)
NEXT_PUBLIC_UMAMI_SCRIPT_URL=https://analytics.infra.mintel.me/script.js
```

### Docker Compose

The `docker-compose.yml` already includes the environment variables:

```yaml
environment:
  - UMAMI_WEBSITE_ID=${UMAMI_WEBSITE_ID}
  - NEXT_PUBLIC_UMAMI_SCRIPT_URL=${NEXT_PUBLIC_UMAMI_SCRIPT_URL:-https://analytics.infra.mintel.me/script.js}
```

## Usage

### 1. Automatic Pageview Tracking

The `AnalyticsProvider` component automatically tracks pageviews on client-side route changes. It's already included in your layout:

```tsx
// app/[locale]/layout.tsx
<NextIntlClientProvider messages={messages} locale={locale}>
  <UmamiScript />
  <Header />
  <main>{children}</main>
  <Footer />
  <AnalyticsProvider />
</NextIntlClientProvider>
```

### 2. Tracking Custom Events

Use the `useAnalytics` hook to track custom events:

```tsx
'use client';

import { useAnalytics } from '@/components/analytics/useAnalytics';
import { AnalyticsEvents } from '@/components/analytics/analytics-events';

function ProductCard({ product }) {
  const { trackEvent } = useAnalytics();

  const handleAddToCart = () => {
    trackEvent(AnalyticsEvents.PRODUCT_ADD_TO_CART, {
      product_id: product.id,
      product_name: product.name,
      product_category: product.category,
      price: product.price,
    });
  };

  return <button onClick={handleAddToCart}>Add to Cart</button>;
}
```

### 3. Tracking Pageviews Manually

```tsx
'use client';

import { useAnalytics } from '@/components/analytics/useAnalytics';

function CustomNavigation() {
  const { trackPageview } = useAnalytics();

  const navigateToCustomPage = () => {
    // Track a custom pageview
    trackPageview('/custom-path?param=value');

    // Then perform navigation
    window.location.href = '/custom-path?param=value';
  };

  return <button onClick={navigateToCustomPage}>Go to Custom Page</button>;
}
```

### 4. Using Predefined Events

The `analytics-events.ts` file provides a centralized list of events:

```tsx
'use client';

import { useAnalytics } from '@/components/analytics/useAnalytics';
import { AnalyticsEvents, AnalyticsEventProperties } from '@/components/analytics/analytics-events';

function ContactForm() {
  const { trackEvent } = useAnalytics();

  const handleSubmit = (formData: FormData) => {
    // Track form submission
    trackEvent(AnalyticsEvents.CONTACT_FORM_SUBMIT, {
      form_id: 'contact-form',
      form_name: 'Contact Us',
      form_fields: {
        name: formData.get('name'),
        email: formData.get('email'),
        message: formData.get('message'),
      },
    });
  };

  return <form onSubmit={handleSubmit}>{/* form fields */}</form>;
}
```

### 5. E-commerce Tracking Example

```tsx
'use client';

import { useAnalytics } from '@/components/analytics/useAnalytics';
import { AnalyticsEvents } from '@/components/analytics/analytics-events';

function ProductPage({ product }) {
  const { trackEvent } = useAnalytics();

  // Track product view on page load
  useEffect(() => {
    trackEvent(AnalyticsEvents.PRODUCT_VIEW, {
      product_id: product.id,
      product_name: product.name,
      product_category: product.category,
      price: product.price,
    });
  }, [product]);

  const handleAddToCart = () => {
    trackEvent(AnalyticsEvents.PRODUCT_ADD_TO_CART, {
      product_id: product.id,
      product_name: product.name,
      product_category: product.category,
      price: product.price,
      quantity: 1,
    });
  };

  const handlePurchase = () => {
    trackEvent(AnalyticsEvents.PRODUCT_PURCHASE, {
      product_id: product.id,
      product_name: product.name,
      product_category: product.category,
      price: product.price,
      transaction_id: 'TXN-12345',
      currency: 'EUR',
    });
  };

  return (
    <div>
      <h1>{product.name}</h1>
      <p>{product.description}</p>
      <button onClick={handleAddToCart}>Add to Cart</button>
      <button onClick={handlePurchase}>Buy Now</button>
    </div>
  );
}
```

### 6. Search & Filter Tracking

```tsx
'use client';

import { useAnalytics } from '@/components/analytics/useAnalytics';
import { AnalyticsEvents } from '@/components/analytics/analytics-events';

function ProductFilter() {
  const { trackEvent } = useAnalytics();

  const handleFilterChange = (filters: Record<string, unknown>) => {
    trackEvent(AnalyticsEvents.FILTER_APPLY, {
      filter_type: 'category',
      filter_value: filters.category,
      filter_count: Object.keys(filters).length,
    });
  };

  const handleSearch = (query: string) => {
    trackEvent(AnalyticsEvents.SEARCH, {
      search_query: query,
      search_results_count: 42, // You'd get this from your search results
    });
  };

  return (
    <div>
      <input onChange={(e) => handleSearch(e.target.value)} />
      <select onChange={(e) => handleFilterChange({ category: e.target.value })}>
        {/* filter options */}
      </select>
    </div>
  );
}
```

### 7. User Account Events

```tsx
'use client';

import { useAnalytics } from '@/components/analytics/useAnalytics';
import { AnalyticsEvents } from '@/components/analytics/analytics-events';

function LoginForm() {
  const { trackEvent } = useAnalytics();

  const handleLogin = (email: string) => {
    trackEvent(AnalyticsEvents.USER_LOGIN, {
      user_email: email,
      login_method: 'email',
    });
  };

  const handleLogout = () => {
    trackEvent(AnalyticsEvents.USER_LOGOUT, {
      user_id: 'user-123',
    });
  };

  return (
    <div>
      <button onClick={() => handleLogin('user@example.com')}>Login</button>
      <button onClick={handleLogout}>Logout</button>
    </div>
  );
}
```

### 8. Error Tracking

```tsx
'use client';

import { useAnalytics } from '@/components/analytics/useAnalytics';
import { AnalyticsEvents } from '@/components/analytics/analytics-events';

function ErrorBoundary({ children }) {
  const { trackEvent } = useAnalytics();

  const handleError = (error: Error, errorInfo: React.ErrorInfo) => {
    trackEvent(AnalyticsEvents.ERROR, {
      error_message: error.message,
      error_stack: error.stack,
      error_component: errorInfo.componentStack,
    });
  };

  return <ErrorBoundary onError={handleError}>{children}</ErrorBoundary>;
}
```

## Event Reference

### Common Events

| Event Name            | Description           | Example Properties                                           |
| --------------------- | --------------------- | ------------------------------------------------------------ |
| `pageview`            | Page view             | `{ url: '/products/123' }`                                   |
| `button_click`        | Button clicked        | `{ button_id: 'cta-primary', page: 'homepage' }`             |
| `link_click`          | Link clicked          | `{ link_url: '/products', link_text: 'View Products' }`      |
| `form_submit`         | Form submitted        | `{ form_id: 'contact-form', form_name: 'Contact Us' }`       |
| `product_view`        | Product page viewed   | `{ product_id: '123', product_name: 'Cable', price: 99.99 }` |
| `product_add_to_cart` | Product added to cart | `{ product_id: '123', quantity: 1 }`                         |
| `product_purchase`    | Product purchased     | `{ product_id: '123', transaction_id: 'TXN-123' }`           |
| `search`              | Search performed      | `{ search_query: 'cable', search_results_count: 42 }`        |
| `filter_apply`        | Filter applied        | `{ filter_type: 'category', filter_value: 'high-voltage' }`  |
| `user_login`          | User logged in        | `{ user_email: 'user@example.com' }`                         |
| `user_signup`         | User signed up        | `{ user_email: 'user@example.com' }`                         |
| `error`               | Error occurred        | `{ error_message: 'Something went wrong' }`                  |

### Custom Events

You can create any custom event by passing a string name:

```tsx
trackEvent('custom_event_name', {
  custom_property: 'value',
  another_property: 123,
});
```

## Best Practices

### 1. Use Centralized Event Definitions

Always use the `AnalyticsEvents` constant for consistency:

```tsx
// ✅ Good
import { AnalyticsEvents } from '@/components/analytics/analytics-events';
trackEvent(AnalyticsEvents.PRODUCT_ADD_TO_CART, { ... });

// ❌ Avoid
trackEvent('product_add_to_cart', { ... }); // Typo risk!
```

### 2. Include Relevant Context

Add context to your events to make them more useful:

```tsx
// ✅ Good
trackEvent(AnalyticsEvents.BUTTON_CLICK, {
  button_id: 'cta-primary',
  page: 'homepage',
  section: 'hero',
  user_type: 'guest',
});

// ❌ Less useful
trackEvent(AnalyticsEvents.BUTTON_CLICK, {
  button_id: 'cta-primary',
});
```

### 3. Track Meaningful Events

Focus on business-critical events:

- ✅ Product views, add to cart, purchases
- ✅ Form submissions (contact, newsletter, quote requests)
- ✅ Search queries and filter usage
- ✅ User authentication events
- ✅ Error occurrences

- ❌ Every mouse move
- ❌ Every scroll event (unless specifically needed)
- ❌ Every hover state change

### 4. Respect Privacy

- Don't track personally identifiable information (PII)
- Don't track sensitive data (passwords, credit cards, etc.)
- Use anonymized IDs where possible
- Follow GDPR and other privacy regulations

### 5. Test in Development

The analytics system includes development mode logging:

```bash
# In development, you'll see console logs:
[Umami] Tracked event: product_add_to_cart { product_id: '123' }
[Umami] Tracked pageview: /products/123
```

## Troubleshooting

### Analytics Not Working

1. **Check environment variables:**

   ```bash
   echo $UMAMI_WEBSITE_ID
   ```

2. **Verify the script is loading:**
   - Open browser DevTools
   - Check Network tab for `script.js` request
   - Check Console for any errors

3. **Check Umami dashboard:**
   - Log into your Umami instance
   - Verify the website ID matches
   - Check if data is being received

### Development Mode

In development mode, you'll see console logs for all tracked events. This helps you verify that events are being tracked correctly without affecting your production analytics.

### Disabling Analytics

To disable analytics (e.g., for local development), simply remove the `UMAMI_WEBSITE_ID` environment variable:

```bash
# .env.local (not committed to git)
# UMAMI_WEBSITE_ID=
```

## Performance

The analytics implementation is optimized for performance:

- ✅ Uses Next.js `Script` component with `afterInteractive` strategy
- ✅ Script loads after page is interactive
- ✅ No blocking of critical rendering path
- ✅ Minimal JavaScript bundle size
- ✅ Automatic cleanup on route changes

## Security

- ✅ Environment variables are not exposed to the client (except `NEXT_PUBLIC_` prefixed ones)
- ✅ Script URL can be customized for self-hosted Umami instances
- ✅ Error handling prevents analytics from breaking your app
- ✅ Type-safe event tracking with TypeScript

## Additional Resources

- [Umami Documentation](https://umami.is/docs)
- [Next.js Script Component](https://nextjs.org/docs/app/api-reference/components/script)
- [Analytics Best Practices](https://umami.is/docs/best-practices)

## Support

For issues or questions about the analytics implementation, check:

1. This README for usage examples
2. The component source code for implementation details
3. The Umami documentation for platform-specific questions
