> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getmilana.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Feature-flagged Rollout

> Roll out Milana to a subset of users using feature flags and deferred initialization.

If you want to enable Milana for a percentage of your users — or gate it behind a feature flag — use **deferred initialization**. The SDK loads but does nothing until you explicitly call `initialize()`.

This lets you control rollout from your existing feature flag system (LaunchDarkly, PostHog, Statsig, etc.) without code changes at each stage.

## How it works

1. Set `shouldDeferInitialization` on the provider (React) or delay calling `init()` (vanilla JS)
2. Wait for your feature flag to resolve
3. Call `initialize()` only when the flag is enabled

If the flag is off, the SDK stays inert — no recording, no network requests.

<Tabs>
  <Tab title="React">
    ```tsx theme={null}
    import { MilanaProvider, useMilana } from "milana-js/react";

    function App() {
      return (
        <MilanaProvider
          shouldDeferInitialization
          productId="prd_YOUR_PRODUCT_ID"
          clientKey="key_YOUR_CLIENT_KEY"
          sessionInfo={{ environment: "production", version: "2.4.1" }}
        >
          <FeatureFlagGate />
          <YourApp />
        </MilanaProvider>
      );
    }

    function FeatureFlagGate() {
      const { initialize } = useMilana();
      const milanaEnabled = useFeatureFlagValue("milana-enabled");

      useEffect(() => {
        if (milanaEnabled) initialize();
      }, [milanaEnabled, initialize]);

      return null;
    }
    ```

    <Info>
      `initialize()` is idempotent — calling it more than once has no effect after the first successful call.
    </Info>
  </Tab>

  <Tab title="Script Tag">
    With the script tag approach, you control rollout by conditionally calling `init()`:

    ```html theme={null}
    <script>
      window._milanaQueue = window._milanaQueue || [];
      function Milana() { window._milanaQueue.push([].slice.call(arguments)); }
    </script>
    <script async src="https://cdn.getmilana.ai/milana.js"></script>

    <script>
      // Wait for your feature flag to resolve, then init
      yourFlagProvider.isEnabled("milana-enabled").then(function (enabled) {
        if (enabled) {
          Milana("init", "prd_YOUR_PRODUCT_ID", "key_YOUR_CLIENT_KEY", {
            environment: "production",
            version: "2.4.1",
          });
        }
      });
    </script>
    ```
  </Tab>
</Tabs>

## Checking initialization state

<Tabs>
  <Tab title="React">
    ```tsx theme={null}
    const { isInitialized } = useMilana();

    // isInitialized is true after init has completed successfully
    ```
  </Tab>

  <Tab title="Script Tag">
    ```javascript theme={null}
    // Enable debug mode to see session state in the console, then reload
    localStorage.setItem("milana_debug_mode", "true");
    ```
  </Tab>
</Tabs>

## Queuing

Calls to `trackEvent()` and `update()` made before initialization completes are automatically queued and replayed once recording starts. You don't need to wait for `isInitialized` before calling them.

<Tip>
  Milana also has built-in [server-side sampling](https://app.getmilana.ai/settings) — you can set a sampling rate in the dashboard to control how many sessions are recorded even after removing your feature flag.
</Tip>
