Compare commits
1 Commits
cloudflare
...
dev/postho
Author | SHA1 | Date | |
---|---|---|---|
|
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_WEBSITE_ID=""
|
||||||
NEXT_PUBLIC_DATAFAST_DOMAIN=""
|
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 GoogleAnalytics from './google-analytics';
|
||||||
import OpenPanelAnalytics from './open-panel-analytics';
|
import OpenPanelAnalytics from './open-panel-analytics';
|
||||||
import { PlausibleAnalytics } from './plausible-analytics';
|
import { PlausibleAnalytics } from './plausible-analytics';
|
||||||
|
import PostHogAnalytics from './posthog-analytics';
|
||||||
import { SelineAnalytics } from './seline-analytics';
|
import { SelineAnalytics } from './seline-analytics';
|
||||||
import { UmamiAnalytics } from './umami-analytics';
|
import { UmamiAnalytics } from './umami-analytics';
|
||||||
|
|
||||||
@ -46,6 +47,9 @@ export function Analytics() {
|
|||||||
{/* seline analytics */}
|
{/* seline analytics */}
|
||||||
<SelineAnalytics />
|
<SelineAnalytics />
|
||||||
|
|
||||||
|
{/* posthog analytics */}
|
||||||
|
<PostHogAnalytics />
|
||||||
|
|
||||||
{/* vercel analytics */}
|
{/* vercel analytics */}
|
||||||
{/* https://vercel.com/docs/analytics/quickstart */}
|
{/* https://vercel.com/docs/analytics/quickstart */}
|
||||||
{websiteConfig.analytics.enableVercelAnalytics && <VercelAnalytics />}
|
{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 { RootProvider } from 'fumadocs-ui/provider';
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import { ThemeProvider, useTheme } from 'next-themes';
|
import { ThemeProvider, useTheme } from 'next-themes';
|
||||||
|
import dynamic from 'next/dynamic';
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
|
|
||||||
|
const PostHogProvider = dynamic(() => import('./posthog-provider'), { ssr: false });
|
||||||
|
|
||||||
interface ProvidersProps {
|
interface ProvidersProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
locale: string;
|
locale: string;
|
||||||
@ -62,11 +65,13 @@ export function Providers({ children, locale }: ProvidersProps) {
|
|||||||
>
|
>
|
||||||
<ActiveThemeProvider>
|
<ActiveThemeProvider>
|
||||||
<RootProvider theme={theme} i18n={{ locale, locales, translations }}>
|
<RootProvider theme={theme} i18n={{ locale, locales, translations }}>
|
||||||
<TooltipProvider>
|
<PostHogProvider>
|
||||||
<PaymentProvider>
|
<TooltipProvider>
|
||||||
<CreditsProvider>{children}</CreditsProvider>
|
<PaymentProvider>
|
||||||
</PaymentProvider>
|
<CreditsProvider>{children}</CreditsProvider>
|
||||||
</TooltipProvider>
|
</PaymentProvider>
|
||||||
|
</TooltipProvider>
|
||||||
|
</PostHogProvider>
|
||||||
</RootProvider>
|
</RootProvider>
|
||||||
</ActiveThemeProvider>
|
</ActiveThemeProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
Loading…
Reference in New Issue
Block a user