# Remix Feature Flags 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

    ## Client-side rendering

    Required

    **Basic flag implementation**

    ```javascript
    if (posthog.isFeatureEnabled('flag-key')) {
        // Do something differently for this user
        // Optional: fetch the payload
        const matchedFlagPayload = posthog.getFeatureFlagPayload('flag-key')
    }
    ```

    **Multivariate flags**

    ```javascript
    if (posthog.getFeatureFlag('flag-key') == 'variant-key') { // replace 'variant-key' with the key of your variant
        // Do something differently for this user
        // Optional: fetch the payload
        const matchedFlagPayload = posthog.getFeatureFlagPayload('flag-key')
    }
    ```

7.  7

    ## Server-side rendering

    Required

    Use `posthog-node` to evaluate feature flags on the server. Initialize PostHog in your API route or loader:

    app/api/example/route.ts

    PostHog AI

    ```typescript
    import { PostHog } from 'posthog-node'
    const posthog = new PostHog(process.env.NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN!, {
        host: process.env.NEXT_PUBLIC_POSTHOG_HOST
    })
    ```

    **Basic flag implementation**

    ```javascript
    const isFeatureFlagEnabled = await client.isFeatureEnabled('flag-key', 'distinct_id_of_your_user')
    if (isFeatureFlagEnabled) {
        // Your code if the flag is enabled
        // Optional: fetch the payload
        const matchedFlagPayload = await client.getFeatureFlagPayload('flag-key', 'distinct_id_of_your_user', isFeatureFlagEnabled)
    }
    ```

    **Multivariate flags**

    ```javascript
    const enabledVariant = await client.getFeatureFlag('flag-key', 'distinct_id_of_your_user')
    if (enabledVariant === 'variant-key') {  // replace 'variant-key' with the key of your variant
        // Do something differently for this user
        // Optional: fetch the payload
        const matchedFlagPayload = await client.getFeatureFlagPayload('flag-key', 'distinct_id_of_your_user', enabledVariant)
    }
    ```

8.  8

    ## Running experiments

    Optional

    Experiments run on top of our feature flags. Once you've implemented the flag in your code, you run an experiment by creating a new experiment in the PostHog dashboard.

9.  9

    ## Next steps

    Recommended

    Now that you're evaluating flags, continue with the resources below to learn what else Feature Flags enables within the PostHog platform.

    | Resource | Description |
    | --- | --- |
    | [Creating a feature flag](/docs/feature-flags/creating-feature-flags.md) | How to create a feature flag in PostHog |
    | [Adding feature flag code](/docs/feature-flags/adding-feature-flag-code.md) | How to check flags in your code for all platforms |
    | [Framework-specific guides](/docs/feature-flags/tutorials.md#framework-guides) | Setup guides for React Native, Next.js, Flutter, and other frameworks |
    | [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
    | [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |

### Community questions

Ask a question

### Was this page useful?

HelpfulCould be better