-
Notifications
You must be signed in to change notification settings - Fork 745
React Router docs #14258
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
React Router docs #14258
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
72f6f0a
React Router docs
gewenyu99 1ef276c
Merge branch 'master' into react
gewenyu99 4baf399
Apply suggestions from code review
gewenyu99 1a9566b
tweaks
gewenyu99 86c0756
Merge branch 'react' of https://github.com/PostHog/posthog.com into r…
gewenyu99 45c37ec
Logos
gewenyu99 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
72 changes: 72 additions & 0 deletions
72
contents/docs/libraries/react-router/_snippets/react-router-decision-tree.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 <RouterProvider>' }, | ||
| { value: 'declarative', label: 'Using <BrowserRouter>' }, | ||
| ], | ||
| }, | ||
| ] | ||
|
|
||
| const getRecommendation = (answers: Record<string, string>): 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 <DecisionTree questions={questions} getRecommendation={getRecommendation} /> | ||
| } | ||
|
|
||
| export default ReactRouterDecisionTree |
15 changes: 15 additions & 0 deletions
15
contents/docs/libraries/react-router/_snippets/step-access-posthog-methods.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| <UsageWarning /> | ||
|
|
||
| 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 <button onClick={() => posthog?.capture('button_clicked')}>Click me</button> | ||
| } | ||
| ``` | ||
|
|
||
| For a complete list of available methods, see the [posthog-js documentation](/docs/libraries/js). | ||
|
|
7 changes: 7 additions & 0 deletions
7
contents/docs/libraries/react-router/_snippets/step-env-variables.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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=<ph_project_api_key> | ||
| VITE_PUBLIC_POSTHOG_HOST=<ph_client_api_host> | ||
| ``` | ||
|
|
33 changes: 33 additions & 0 deletions
33
contents/docs/libraries/react-router/_snippets/step-identify-user.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 ( | ||
| <div> | ||
| {/* ... existing code ... */} | ||
| <button onClick={handleLogin}>Login</button> | ||
| </div> | ||
| ); | ||
| } | ||
| ``` | ||
|
|
||
| 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. | ||
|
|
2 changes: 2 additions & 0 deletions
2
contents/docs/libraries/react-router/_snippets/step-install-client-sdks.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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. | ||
|
|
11 changes: 11 additions & 0 deletions
11
contents/docs/libraries/react-router/_snippets/step-next-steps.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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. | ||
|
|
15 changes: 15 additions & 0 deletions
15
contents/docs/libraries/react-router/_snippets/step-verify-client-events.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 <button onClick={() => posthog?.capture('button_clicked')}>Click me</button> | ||
| } | ||
| ``` | ||
|
|
||
| You should see these events in a minute or two in the [activity tab](https://app.posthog.com/activity/explore). | ||
|
|
71 changes: 71 additions & 0 deletions
71
contents/docs/libraries/react-router/_snippets/tracking-element-visibility.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 ( | ||
| <PostHogCaptureOnViewed name="hero-banner"> | ||
| <div>Your important content here</div> | ||
| </PostHogCaptureOnViewed> | ||
| ) | ||
| } | ||
| ``` | ||
|
|
||
| **With custom properties:** | ||
|
|
||
| You can include additional properties with the event to provide more context: | ||
|
|
||
| ```react | ||
| <PostHogCaptureOnViewed | ||
| name="product-card" | ||
| properties={{ | ||
| product_id: '123', | ||
| category: 'electronics', | ||
| price: 299.99 | ||
| }} | ||
| > | ||
| <ProductCard /> | ||
| </PostHogCaptureOnViewed> | ||
| ``` | ||
|
|
||
| **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 | ||
| <PostHogCaptureOnViewed | ||
| name="product-gallery" | ||
| properties={{ gallery_type: 'featured' }} | ||
| trackAllChildren | ||
| > | ||
| <ProductCard id="1" /> | ||
| <ProductCard id="2" /> | ||
| <ProductCard id="3" /> | ||
| </PostHogCaptureOnViewed> | ||
| ``` | ||
|
|
||
| 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 | ||
| <PostHogCaptureOnViewed | ||
| name="footer" | ||
| observerOptions={{ | ||
| threshold: 0.5, // Element is 50% visible | ||
| rootMargin: '0px' | ||
| }} | ||
| > | ||
| <Footer /> | ||
| </PostHogCaptureOnViewed> | ||
| ``` | ||
|
|
||
| The component passes all other props to the wrapper `div`, so you can add styling, classes, or other HTML attributes as needed. | ||
|
|
16 changes: 16 additions & 0 deletions
16
contents/docs/libraries/react-router/_snippets/typeerror-section.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| If you see the error `TypeError: Cannot read properties of undefined (reading '...')` this is likely because you tried to call a posthog function when posthog was not initialized (such as during the initial render). On purpose, we still render the children even if PostHog is not initialized so that your app still loads even if PostHog can't load. | ||
|
|
||
| To fix this error, add a check that posthog has been initialized such as: | ||
|
|
||
| ```react | ||
| useEffect(() => { | ||
| posthog?.capture('test') // using optional chaining (recommended) | ||
|
|
||
| if (posthog) { | ||
| posthog.capture('test') // using an if statement | ||
| } | ||
| }, [posthog]) | ||
| ``` | ||
|
|
||
| Typescript helps protect against these errors. | ||
|
|
6 changes: 6 additions & 0 deletions
6
contents/docs/libraries/react-router/_snippets/usage-warning.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| <CalloutBox icon="IconWarning" title="Don't directly import PostHog" type="caution"> | ||
|
|
||
| When using React Router, you should not directly import `posthog` from `posthog-js` other than during initialization. Instead, use the `usePostHog` hook to access the PostHog client to ensure PostHog is initialized before use. | ||
|
|
||
| </CalloutBox> | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| --- | ||
| title: React Router | ||
| sidebarTitle: React Router | ||
| sidebar: Docs | ||
| showTitle: true | ||
| github: 'https://github.com/PostHog/posthog-js' | ||
| platformLogo: reactRouter | ||
| features: | ||
| eventCapture: true | ||
| userIdentification: true | ||
| autoCapture: true | ||
| sessionRecording: true | ||
| featureFlags: true | ||
| groupAnalytics: true | ||
| surveys: true | ||
| llmAnalytics: false | ||
| errorTracking: true | ||
| --- | ||
|
|
||
| import Tab from "components/Tab" | ||
| import ReactInstall from '../../integrate/_snippets/install-react.mdx' | ||
| import ReactRouterDecisionTree from './_snippets/react-router-decision-tree' | ||
|
|
||
| This guide walks you through setting up PostHog for React Router. React Router V7 has [**three** distinct](https://reactrouter.com/start/modes) modes, and each requires a different setup. If you're still on React Router V6, we have a guide for that, too. | ||
|
|
||
| ## Which version/mode am I using? | ||
|
|
||
| <ReactRouterDecisionTree /> | ||
|
|
||
| <details> | ||
| <summary>Differentiating between React Router versions and modes</summary> | ||
|
|
||
| Here's are quick tips to help you figure out which version/mode you're using: | ||
|
|
||
| First, check your `package.json` file for the `react-router` version. If it's `7.x.x`, you're using React Router V7. If it's `6.x.x`, you're using React Router V6. | ||
|
|
||
| Then check your project to distinguish between the different modes: | ||
| - If you see a `react-router.config.ts` file, you're using React Router V7 in framework mode. | ||
| - If your router is configured like this: `<RouterProvider router={router} />` with router being a `createBrowserRouter` instance, you're using React Router V7 in data mode. | ||
| - Finally, if your router has `<Routes>` and `<Route>` elements, you're using React Router V7 in declarative mode. | ||
|
|
||
| Follow the [React Router docs](https://reactrouter.com/start/modes) for more details. | ||
|
|
||
| </details> | ||
|
|
||
| ## React Router guides | ||
|
|
||
| React Router V7 has [**three** distinct](https://reactrouter.com/start/modes) modes, and each requires a different setup. Some modes require only the client-side React SDK, while others require **both** the client-side React SDK and the server-side Node SDK. | ||
|
|
||
| Follow the [React Router docs](https://reactrouter.com/start/modes) to find out which mode you're using, then follow the guide for that mode: | ||
|
|
||
| | Guide | Description | | ||
| |------|-------------| | ||
| | [V7 - Framework mode (Remix V3)](/docs/libraries/react-router/react-router-v7-framework-mode) | This is the default mode. In framework mode, React Router functions as an SSR (server-side rendering) framework. | | ||
| | [V7 - Declarative mode](/docs/libraries/react-router/react-router-v7-declarative-mode) | In declarative mode, you can build SPAs (single-page applications) with basic routing. | | ||
| | [V7 - Data mode](/docs/libraries/react-router/react-router-v7-data-mode) | Data mode is also for building SPAs, but comes with APIs like loader, action, and useFetcher. | | ||
| | [React Router V6](/docs/libraries/react-router/react-router-v6) | React Router V6 is for building SPAs and has features similar to React Router V7 in declarative or data mode. | | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.