> ## 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.

# Stop Recording

> End the current recording session immediately and allow a fresh session on the next init().

Call `stopRecording()` to programmatically end the current recording session. Common reasons to reach for it:

* **Logout flows** — stop recording when the user signs out
* **End of a workflow** — close the session at the end of a multi-step flow so it shows up as a discrete recording in the dashboard
* **Testing / QA tools** — explicitly finalize a session without waiting for the page to unload

Milana tells the server to finalize the session immediately (instead of waiting for the backend's inactivity timeout), flushes any buffered events, tears down all local recording machinery, and clears the cached session ID so a subsequent [`init()`](/sdk/init) call starts a brand-new session.

<Tip>
  `init()` is fully supported after `stopRecording()` — you'll get a fresh `sessionId` and a completely independent recording. Use this pattern when you need to explicitly segment recordings per user or per flow.
</Tip>

<Tabs>
  <Tab title="React">
    Use the `useMilana()` hook:

    ```tsx theme={null}
    import { useMilana } from "milana-js/react";

    function LogoutButton() {
      const { stopRecording } = useMilana();

      const handleLogout = async () => {
        await stopRecording();
        await signOut();
      };

      return <button onClick={handleLogout}>Log out</button>;
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```typescript theme={null}
    import { stopRecording } from "milana-js";

    await stopRecording();
    ```

    ### Stop, then start a fresh session

    ```typescript theme={null}
    import { init, stopRecording } from "milana-js";

    await stopRecording();

    await init("prd_YOUR_PRODUCT_ID", "key_YOUR_CLIENT_KEY", {
      environment: "production",
      version: "1.0.0",
    });
    ```
  </Tab>

  <Tab title="Script Tag">
    ```javascript theme={null}
    Milana("stopRecording");
    ```
  </Tab>
</Tabs>

***

## Return value

<ResponseField name="success" type="boolean">
  `true` if a session was active and has been torn down. `false` if there was no active session.
</ResponseField>

## Behavior

When you call `stopRecording()`:

* The SDK sends a close signal to the server (`isClientAbort: true` with `clientAbortReason: "CLIENT_STOPPED"`) so the session is finalized immediately rather than waiting for the backend's inactivity timeout.
* Any buffered events are flushed in the same request.
* Local rrweb recording, event observers, interval timers, and the `pagehide` listener are removed.
* `sessionStorage.sessionId` is cleared so a subsequent `init()` starts a brand-new session rather than resuming the one you just closed.

`stopRecording()` is idempotent — calling it when no session is active simply resolves with `{ success: false }`.
