diff --git a/contents/docs/integrate/_snippets/install-react.mdx b/contents/docs/integrate/_snippets/install-react.mdx index 3a7cfd6762eb..f4b003f98ffe 100644 --- a/contents/docs/integrate/_snippets/install-react.mdx +++ b/contents/docs/integrate/_snippets/install-react.mdx @@ -1,4 +1,4 @@ -> For Next.js, we recommend following the [Next.js integration guide](/docs/integrate/next-js) instead. +> For React-based frameworks, we recommend the [Next.js integration guide](/docs/libraries/next-js) and [Next.js integration guide](/docs/libraries/remix) instead. 1. Install [`posthog-js`](https://github.com/posthog/posthog-js) and `@posthog/react` using your package manager: @@ -6,14 +6,14 @@ import InstallReactPackageManagers from "./install-react-package-managers.mdx" -2. Add your environment variables to your `.env.local` file and to your hosting provider (e.g. Vercel, Netlify, AWS). You can find your project API key and host in [your project settings](https://us.posthog.com/settings/project). Including `VITE_PUBLIC_` in their names ensures they are accessible in the frontend. +2. Add your environment variables to your `.env.local` file and to your hosting provider (e.g. Vercel, Netlify, AWS). You can find your project API key and host in [your project settings](https://us.posthog.com/settings/project). If you're using Vite, include `VITE_PUBLIC_` in their names ensures they are accessible in the frontend. ```shell file=.env.local VITE_PUBLIC_POSTHOG_KEY= VITE_PUBLIC_POSTHOG_HOST= ``` -3. Integrate PostHog at the root of your app (such as `main.jsx` if you are using Vite). +3. Integrate PostHog at the root of your app (such as `main.jsx` for Vite apps and `root.tsx` for React Router V7). ```react // src/main.jsx @@ -21,19 +21,19 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' import App from './App.jsx' -import posthog from 'posthog-js'; -import { PostHogProvider } from '@posthog/react' +import posthog from 'posthog-js'; // + +import { PostHogProvider } from '@posthog/react' // + -posthog.init(import.meta.env.VITE_PUBLIC_POSTHOG_KEY, { - api_host: import.meta.env.VITE_PUBLIC_POSTHOG_HOST, - defaults: '', -}); +posthog.init(import.meta.env.VITE_PUBLIC_POSTHOG_KEY, { // + + api_host: import.meta.env.VITE_PUBLIC_POSTHOG_HOST, // + + defaults: '', // + +}); // + createRoot(document.getElementById('root')).render( - + // + - + // + , ) ``` @@ -45,22 +45,3 @@ import CalloutBox from 'components/Docs/CalloutBox' Do not directly import `posthog` apart from installation as shown above. This will likely cause errors as the library might not be initialized yet. Initialization is handled automatically when you use the `PostHogProvider` and `usePostHog` hook. - -
- Using React Router v7? - - You need to set `posthog-js` and `@posthog/react` as external packages in your `vite.config.ts` file to avoid SSR errors. - - ```ts file=vite.config.ts - // ... imports - - export default defineConfig({ - plugins: [tailwindcss(), reactRouter(), tsconfigPaths()], - ssr: { - noExternal: ['posthog-js', '@posthog/react'] - } - }); - ``` - - See our [Remix docs](/docs/libraries/remix) for more details. -
\ No newline at end of file diff --git a/contents/docs/libraries/react-router/_snippets/react-router-decision-tree.tsx b/contents/docs/libraries/react-router/_snippets/react-router-decision-tree.tsx new file mode 100644 index 000000000000..9dd94d3f5a6c --- /dev/null +++ b/contents/docs/libraries/react-router/_snippets/react-router-decision-tree.tsx @@ -0,0 +1,72 @@ +import React from 'react' +import { DecisionTree } from 'components/Docs/DecisionTree' +import type { DecisionTreeQuestion, DecisionTreeRecommendation } from 'components/Docs/DecisionTree' + +const questions: DecisionTreeQuestion[] = [ + { + id: 'version', + question: 'Pick the right guide for you', + description: 'Check your package.json file for the react-router version.', + options: [ + { value: 'v7', label: '7.x.x (React Router V7)' }, + { value: 'v6', label: '6.x.x (React Router V6)' }, + ], + }, + { + id: 'v7-mode', + question: 'Which React Router V7 mode are you using?', + description: 'How are your routes configured and defined?', + condition: (answers) => answers.version === 'v7', + options: [ + { value: 'framework', label: 'Using react-router.config.ts' }, + { value: 'data', label: 'Using ' }, + { value: 'declarative', label: 'Using ' }, + ], + }, +] + +const getRecommendation = (answers: Record): DecisionTreeRecommendation => { + if (answers.version === 'v6') { + return { + title: 'React Router V6', + path: '/docs/libraries/react-router/react-router-v6', + reason: 'You are using React Router V6. Follow the React Router V6 guide for setup instructions.', + } + } + + if (answers['v7-mode'] === 'framework') { + return { + title: 'React Router V7 - Framework mode', + path: '/docs/libraries/react-router/react-router-v7-framework-mode', + reason: 'You are using React Router V7 in framework mode (Remix V3). This is the default mode and functions as an SSR framework.', + } + } + + if (answers['v7-mode'] === 'data') { + return { + title: 'React Router V7 - Data mode', + path: '/docs/libraries/react-router/react-router-v7-data-mode', + reason: 'You are using React Router V7 in data mode. This mode is for building SPAs with APIs like loader, action, and useFetcher.', + } + } + + if (answers['v7-mode'] === 'declarative') { + return { + title: 'React Router V7 - Declarative mode', + path: '/docs/libraries/react-router/react-router-v7-declarative-mode', + reason: 'You are using React Router V7 in declarative mode. This mode is for building SPAs with basic routing.', + } + } + + return { + title: 'React Router setup', + path: '/docs/libraries/react-router', + reason: 'Follow the React Router docs to identify your version and mode.', + } +} + +const ReactRouterDecisionTree: React.FC = () => { + return +} + +export default ReactRouterDecisionTree diff --git a/contents/docs/libraries/react-router/_snippets/step-access-posthog-methods.mdx b/contents/docs/libraries/react-router/_snippets/step-access-posthog-methods.mdx new file mode 100644 index 000000000000..331085f40dfc --- /dev/null +++ b/contents/docs/libraries/react-router/_snippets/step-access-posthog-methods.mdx @@ -0,0 +1,15 @@ + + +On the client-side, you can access the PostHog client using the `usePostHog` hook. This hook returns the initialized PostHog client, which you can use to call PostHog methods. For example: + +```tsx +import { usePostHog } from '@posthog/react' + +function App() { + const posthog = usePostHog() + return +} +``` + +For a complete list of available methods, see the [posthog-js documentation](/docs/libraries/js). + diff --git a/contents/docs/libraries/react-router/_snippets/step-env-variables.mdx b/contents/docs/libraries/react-router/_snippets/step-env-variables.mdx new file mode 100644 index 000000000000..b96561e6eb8a --- /dev/null +++ b/contents/docs/libraries/react-router/_snippets/step-env-variables.mdx @@ -0,0 +1,7 @@ +Add your environment variables to your `.env.local` file and to your hosting provider (e.g. Vercel, Netlify, AWS). You can find your project API key and host in [your project settings](https://us.posthog.com/settings/project). If you're using Vite, including `VITE_PUBLIC_` in their names ensures they are accessible in the frontend. + +```shell file=.env.local +VITE_PUBLIC_POSTHOG_KEY= +VITE_PUBLIC_POSTHOG_HOST= +``` + diff --git a/contents/docs/libraries/react-router/_snippets/step-identify-user.mdx b/contents/docs/libraries/react-router/_snippets/step-identify-user.mdx new file mode 100644 index 000000000000..14a865bd1acc --- /dev/null +++ b/contents/docs/libraries/react-router/_snippets/step-identify-user.mdx @@ -0,0 +1,33 @@ +Now that you can capture basic client-side events, you'll want to identify your user so you can associate users with captured events. + +Generally, you identify users when they log in or when they input some identifiable information (e.g. email, name, etc.). You can identify users by calling the `identify` method on the PostHog client: + +```tsx +export default function Login() { + const { user, login } = useAuth(); + const posthog = usePostHog(); // + + + const handleLogin = async (e: React.FormEvent) => { + // existing code to handle login... + const user = await login({ email, password }); + + posthog?.identify(user.email, // + + { // + + email: user.email, // + + name: user.name, // + + } // + + ); // + + posthog?.capture('user_logged_in'); // + + }; + + return ( +
+ {/* ... existing code ... */} + +
+ ); +} +``` + +PostHog automatically generates anonymous IDs for users before they're identified. When you call identify, a new identified person is created. All previous events tracked with the anonymous ID link to the new identified distinct ID, and all future captures on the same browser associate with the identified person. + diff --git a/contents/docs/libraries/react-router/_snippets/step-install-client-sdks.mdx b/contents/docs/libraries/react-router/_snippets/step-install-client-sdks.mdx new file mode 100644 index 000000000000..5431fa8042c7 --- /dev/null +++ b/contents/docs/libraries/react-router/_snippets/step-install-client-sdks.mdx @@ -0,0 +1,2 @@ +First, you'll need to install [`posthog-js`](https://github.com/posthog/posthog-js) and `@posthog/react` using your package manager. These packages allow you to capture **client-side** events. + diff --git a/contents/docs/libraries/react-router/_snippets/step-next-steps.mdx b/contents/docs/libraries/react-router/_snippets/step-next-steps.mdx new file mode 100644 index 000000000000..1c8b1ce93220 --- /dev/null +++ b/contents/docs/libraries/react-router/_snippets/step-next-steps.mdx @@ -0,0 +1,11 @@ +Now that you've set up PostHog for React Router, you can start capturing events and exceptions in your app. + +To get the most out of PostHog, you should familiarize yourself with the following: + +- [PostHog Web SDK docs](/docs/libraries/js): Learn more about the PostHog Web SDK and how to use it on the client-side. +- [PostHog Node SDK docs](/docs/libraries/node): Learn more about the PostHog Node SDK and how to use it on the server-side. +- [Identify users](/docs/product-analytics/identify): Learn more about how to identify users in your app. +- [Group analytics](/docs/product-analytics/group-analytics): Learn more about how to use group analytics in your app. +- [PostHog AI](/docs/posthog-ai): After capturing events, use PostHog AI to help you understand your data and build insights. +- [Feature flags and experiments](/docs/libraries/react#feature-flags): Feature flag and experiment setup is the same as React. You can find more details in the React integration guide. + diff --git a/contents/docs/libraries/react-router/_snippets/step-verify-client-events.mdx b/contents/docs/libraries/react-router/_snippets/step-verify-client-events.mdx new file mode 100644 index 000000000000..3807a5f67e23 --- /dev/null +++ b/contents/docs/libraries/react-router/_snippets/step-verify-client-events.mdx @@ -0,0 +1,15 @@ +At this point, you should be able to capture client-side events and see them in your PostHog project. This includes basic events like page views and button clicks that are [autocaptured](/docs/product-analytics/autocapture). + +You can also try to capture a custom event to verify it's working. You can access PostHog in any component using the `usePostHog` hook. + +```tsx +import { usePostHog } from '@posthog/react' + +function App() { + const posthog = usePostHog() + return +} +``` + +You should see these events in a minute or two in the [activity tab](https://app.posthog.com/activity/explore). + diff --git a/contents/docs/libraries/react-router/_snippets/tracking-element-visibility.mdx b/contents/docs/libraries/react-router/_snippets/tracking-element-visibility.mdx new file mode 100644 index 000000000000..99f7d03c4b14 --- /dev/null +++ b/contents/docs/libraries/react-router/_snippets/tracking-element-visibility.mdx @@ -0,0 +1,71 @@ +The `PostHogCaptureOnViewed` component enables you to automatically capture events when elements scroll into view in the browser. This is useful for tracking impressions of important content, monitoring user engagement with specific sections, or understanding which parts of your page users are actually seeing. + +The component wraps your content and sends a `$element_viewed` event to PostHog when the wrapped element becomes visible in the viewport. It only fires once per component instance. + +**Basic usage:** + +```react +import { PostHogCaptureOnViewed } from '@posthog/react' + +function App() { + return ( + +
Your important content here
+
+ ) +} +``` + +**With custom properties:** + +You can include additional properties with the event to provide more context: + +```react + + + +``` + +**Tracking multiple children:** + +Use `trackAllChildren` to track each child element separately. This is useful for galleries or lists where you want to know which specific items were viewed: + +```react + + + + + +``` + +When `trackAllChildren` is enabled, each child element sends its own event with a `child_index` property indicating its position. + +**Custom intersection observer options:** + +You can customize when elements are considered "viewed" by passing options to the `IntersectionObserver`: + +```react + +