# Remix web analytics installation - Docs

1.  1

    ## Install the package

    Required

    **Remix version**

    This guide is for Remix v2. For Remix v3, see our [React Router v7 docs](/docs/libraries/react-router.md).

    Install the PostHog JavaScript library using your package manager:

    PostHog AI

    ### npm

    ```bash
    npm install posthog-js
    ```

    ### yarn

    ```bash
    yarn add posthog-js
    ```

    ### pnpm

    ```bash
    pnpm add posthog-js
    ```

2.  2

    ## Configure Vite

    Required

    Add `posthog-js` and `posthog-js/react` to `ssr.noExternal` in your `vite.config.ts` so they get bundled for SSR:

    vite.config.ts

    PostHog AI

    ```typescript
    // ... imports and rest of config
    export default defineConfig({
      plugins: [
        remix({
          future: {
            v3_fetcherPersist: true,
            v3_relativeSplatPath: true,
            v3_throwAbortReason: true,
            v3_singleFetch: true,
            v3_lazyRouteDiscovery: true,
          },
        }),
        tsconfigPaths(),
      ],
      ssr: {
        noExternal: ["posthog-js", "posthog-js/react"],
      },
    });
    ```

3.  3

    ## Create a provider

    Required

    Create a `provider.tsx` file in the app folder. Set up the PostHog provider to initialize after hydration:

    app/provider.tsx

    PostHog AI

    ```typescript
    import { useEffect, useState } from "react";
    import posthog from "posthog-js";
    import { PostHogProvider } from "posthog-js/react";
    export function PHProvider({ children }: { children: React.ReactNode }) {
      const [hydrated, setHydrated] = useState(false);
      useEffect(() => {
        posthog.init("<ph_project_token>", {
          api_host: "https://us.i.posthog.com",
          defaults: "2026-01-30"
        });
        setHydrated(true);
      }, []);
      if (!hydrated) return <>{children}</>;
      return <PostHogProvider client={posthog}>{children}</PostHogProvider>;
    }
    ```

4.  4

    ## Wrap your app

    Required

    Import the `PHProvider` component in your `app/root.tsx` file and use it to wrap your app:

    app/root.tsx

    PostHog AI

    ```typescript
    // ... imports
    import { PHProvider } from "./provider";
    // ... links, meta, etc.
    export function Layout({ children }: { children: React.ReactNode }) {
      return (
        <html lang="en">
          <head>
            <meta charSet="utf-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1" />
            <Meta />
            <Links />
          </head>
          <body>
            <PHProvider>
              {children}
              <ScrollRestoration />
              <Scripts />
            </PHProvider>
          </body>
        </html>
      );
    }
    export default function App() {
      return <Outlet />;
    }
    ```

5.  5

    ## Send events

    Click around and view a couple pages to generate some events. PostHog automatically captures pageviews, clicks, and other interactions for you.

    If you'd like, you can also manually capture custom events:

    JavaScript

    PostHog AI

    ```javascript
    posthog.capture('my_custom_event', { property: 'value' })
    ```

6.  6

    ## Next steps

    Recommended

    After installing PostHog and ensuring [autocapture](/docs/data/autocapture.md) is enabled, head to your [web analytics dashboard](/docs/web-analytics/dashboard.md) to see your data. And then check out our [getting started](/docs/web-analytics/getting-started.md) guide.

    > **PostHog tip:** Web analytics works with [anonymous events](/docs/data/anonymous-vs-identified-events.md). This means if you are primarily using PostHog for web analytics, it can be significantly cheaper for you.

### Community questions

Ask a question

### Was this page useful?

HelpfulCould be better