feat: support posthog analytics
This commit is contained in:
parent
2b72570784
commit
ada95848f9
95
POSTHOG_SETUP.md
Normal file
95
POSTHOG_SETUP.md
Normal file
@ -0,0 +1,95 @@
|
||||
# PostHog Analytics Setup Guide
|
||||
|
||||
This guide will help you set up PostHog analytics for your MkSaaS application.
|
||||
|
||||
## Quick Setup
|
||||
|
||||
### 1. Get PostHog API Key
|
||||
|
||||
1. Go to [PostHog](https://posthog.com) and create an account
|
||||
2. Create a new project (or use an existing one)
|
||||
3. Go to **Project Settings** → **API Keys**
|
||||
4. Copy your **Project API Key** (starts with `phc_`)
|
||||
|
||||
### 2. Configure Environment Variables
|
||||
|
||||
Add the following variables to your `.env.local` file:
|
||||
|
||||
```bash
|
||||
# PostHog Analytics
|
||||
NEXT_PUBLIC_POSTHOG_KEY=your_posthog_project_key_here
|
||||
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
|
||||
```
|
||||
|
||||
**Note:** The default host `https://us.i.posthog.com` works for most users. If you're using PostHog Cloud EU, use `https://eu.i.posthog.com` instead.
|
||||
|
||||
### 3. Install Dependencies
|
||||
|
||||
If PostHog isn't already installed, run:
|
||||
|
||||
```bash
|
||||
pnpm add posthog-js
|
||||
```
|
||||
|
||||
### 4. Verify Setup
|
||||
|
||||
1. Start your development server: `pnpm dev`
|
||||
2. Open your browser and visit `http://localhost:3000`
|
||||
3. Check the browser's developer console for any errors
|
||||
4. In PostHog dashboard, go to **Live Events** to see real-time tracking
|
||||
|
||||
## Available Environment Variables
|
||||
|
||||
| Variable | Description | Example |
|
||||
|----------|-------------|---------|
|
||||
| `NEXT_PUBLIC_POSTHOG_KEY` | Your PostHog project API key | `phc_abc123...` |
|
||||
| `NEXT_PUBLIC_POSTHOG_HOST` | PostHog instance URL | `https://us.i.posthog.com` |
|
||||
|
||||
## Features Included
|
||||
|
||||
The integration includes:
|
||||
|
||||
- **Page view tracking** - Automatic tracking of all page views
|
||||
- **Custom event capture** - Ready to use with your own events
|
||||
- **User identification** - Links events to logged-in users
|
||||
- **Cross-domain tracking** - Works with your domain setup
|
||||
- **Performance tracking** - Monitors page load times
|
||||
|
||||
## Custom Events Usage
|
||||
|
||||
You can track custom events in your components:
|
||||
|
||||
```typescript
|
||||
import { usePostHog } from 'posthog-js/react';
|
||||
|
||||
function MyComponent() {
|
||||
const posthog = usePostHog();
|
||||
|
||||
const handleClick = () => {
|
||||
posthog.capture('button_clicked', {
|
||||
button_name: 'upgrade_plan',
|
||||
user_tier: 'free'
|
||||
});
|
||||
};
|
||||
|
||||
return <button onClick={handleClick}>Upgrade</button>;
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Events not appearing in PostHog?
|
||||
1. Check that `NEXT_PUBLIC_POSTHOG_KEY` is set correctly
|
||||
2. Verify the API key starts with `phc_`
|
||||
3. Ensure you're in production mode or events won't be sent in development
|
||||
4. Check the browser console for any JavaScript errors
|
||||
|
||||
### Development vs Production
|
||||
- **Development**: Events are only sent if you manually enable them
|
||||
- **Production**: Events are automatically sent when environment variables are configured
|
||||
|
||||
### Next Steps
|
||||
- Explore [PostHog documentation](https://posthog.com/docs) for advanced features
|
||||
- Set up user properties and cohorts
|
||||
- Create custom dashboards and insights
|
||||
- Consider setting up feature flags for A/B testing
|
@ -129,6 +129,12 @@ NEXT_PUBLIC_SELINE_TOKEN=""
|
||||
# -----------------------------------------------------------------------------
|
||||
NEXT_PUBLIC_DATAFAST_WEBSITE_ID=""
|
||||
NEXT_PUBLIC_DATAFAST_DOMAIN=""
|
||||
# -----------------------------------------------------------------------------
|
||||
# PostHog Analytics (https://posthog.com)
|
||||
# https://mksaas.com/docs/analytics#posthog
|
||||
# -----------------------------------------------------------------------------
|
||||
NEXT_PUBLIC_POSTHOG_KEY=""
|
||||
NEXT_PUBLIC_POSTHOG_HOST="https://us.i.posthog.com"
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
@ -6,6 +6,7 @@ import DataFastAnalytics from './data-fast-analytics';
|
||||
import GoogleAnalytics from './google-analytics';
|
||||
import OpenPanelAnalytics from './open-panel-analytics';
|
||||
import { PlausibleAnalytics } from './plausible-analytics';
|
||||
import PostHogAnalytics from './posthog-analytics';
|
||||
import { SelineAnalytics } from './seline-analytics';
|
||||
import { UmamiAnalytics } from './umami-analytics';
|
||||
|
||||
@ -46,6 +47,9 @@ export function Analytics() {
|
||||
{/* seline analytics */}
|
||||
<SelineAnalytics />
|
||||
|
||||
{/* posthog analytics */}
|
||||
<PostHogAnalytics />
|
||||
|
||||
{/* vercel analytics */}
|
||||
{/* https://vercel.com/docs/analytics/quickstart */}
|
||||
{websiteConfig.analytics.enableVercelAnalytics && <VercelAnalytics />}
|
||||
|
40
src/analytics/posthog-analytics.tsx
Normal file
40
src/analytics/posthog-analytics.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
'use client';
|
||||
|
||||
import { usePathname, useSearchParams } from 'next/navigation';
|
||||
import { usePostHog } from 'posthog-js/react';
|
||||
import { useEffect, Suspense } from 'react';
|
||||
|
||||
function PostHogPageView() {
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
const posthog = usePostHog();
|
||||
|
||||
useEffect(() => {
|
||||
if (pathname && posthog) {
|
||||
let url = window.origin + pathname;
|
||||
if (searchParams.toString()) {
|
||||
url = `${url}?${searchParams.toString()}`;
|
||||
}
|
||||
posthog.capture('$pageview', {
|
||||
$current_url: url,
|
||||
});
|
||||
}
|
||||
}, [pathname, searchParams, posthog]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export default function PostHogAnalytics() {
|
||||
const key = process.env.NEXT_PUBLIC_POSTHOG_KEY;
|
||||
const host = process.env.NEXT_PUBLIC_POSTHOG_HOST;
|
||||
|
||||
if (!key || !host) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Suspense fallback={null}>
|
||||
<PostHogPageView />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
34
src/app/[locale]/posthog-provider.tsx
Normal file
34
src/app/[locale]/posthog-provider.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
'use client';
|
||||
|
||||
import posthog from 'posthog-js';
|
||||
import { PostHogProvider } from 'posthog-js/react';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
interface PostHogClientProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export default function PostHogClientProvider({
|
||||
children,
|
||||
}: PostHogClientProviderProps) {
|
||||
const key = process.env.NEXT_PUBLIC_POSTHOG_KEY;
|
||||
const host = process.env.NEXT_PUBLIC_POSTHOG_HOST;
|
||||
|
||||
useEffect(() => {
|
||||
if (key && host && typeof window !== 'undefined' && !posthog.__loaded) {
|
||||
posthog.init(key, {
|
||||
api_host: host,
|
||||
person_profiles: 'identified_only',
|
||||
capture_pageview: false, // Disable automatic pageview capture, as we capture manually
|
||||
capture_pageleave: true,
|
||||
});
|
||||
}
|
||||
}, [key, host]);
|
||||
|
||||
if (!key || !host) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
return <PostHogProvider client={posthog}>{children}</PostHogProvider>;
|
||||
}
|
||||
|
@ -9,8 +9,11 @@ import type { Translations } from 'fumadocs-ui/i18n';
|
||||
import { RootProvider } from 'fumadocs-ui/provider';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { ThemeProvider, useTheme } from 'next-themes';
|
||||
import dynamic from 'next/dynamic';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
const PostHogProvider = dynamic(() => import('./posthog-provider'), { ssr: false });
|
||||
|
||||
interface ProvidersProps {
|
||||
children: ReactNode;
|
||||
locale: string;
|
||||
@ -62,11 +65,13 @@ export function Providers({ children, locale }: ProvidersProps) {
|
||||
>
|
||||
<ActiveThemeProvider>
|
||||
<RootProvider theme={theme} i18n={{ locale, locales, translations }}>
|
||||
<TooltipProvider>
|
||||
<PaymentProvider>
|
||||
<CreditsProvider>{children}</CreditsProvider>
|
||||
</PaymentProvider>
|
||||
</TooltipProvider>
|
||||
<PostHogProvider>
|
||||
<TooltipProvider>
|
||||
<PaymentProvider>
|
||||
<CreditsProvider>{children}</CreditsProvider>
|
||||
</PaymentProvider>
|
||||
</TooltipProvider>
|
||||
</PostHogProvider>
|
||||
</RootProvider>
|
||||
</ActiveThemeProvider>
|
||||
</ThemeProvider>
|
||||
|
Loading…
Reference in New Issue
Block a user