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

# Hooks

<View title="Developer" />

<View title="Federal docs" />

<View title="EU docs" />

This topic explains how to define and add hooks to LaunchDarkly SDKs. Hooks are collections of developer-defined callbacks. They contain methods that the SDK executes at various points of interest.

In LaunchDarkly SDKs, hooks provide entry points to observe or modify aspects of SDK operation. For example, when you [enable OpenTelemetry in a server-side SDK](/docs/sdk/features/opentelemetry-server-side), you add a tracing hook, provided by LaunchDarkly, that surfaces telemetry data. You might also write your own hook, for instance to support logging or reporting errors.

## Hooks stages

LaunchDarkly SDKs provide the following series of hooks:

<table>
  <thead>
    <tr>
      <th>Series</th>
      <th>Stages</th>
      <th>Execution</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>Evaluation</td>
      <td>`beforeEvaluation`, `afterEvaluation`</td>
      <td>When you include a hook in your SDK configuration, the SDK executes these two stages before and after you [evaluate a feature flag](/docs/sdk/features/evaluating).</td>
    </tr>

    <tr>
      <td>Identify</td>
      <td>`beforeIdentify`, `afterIdentify`</td>
      <td>When you include a hook in your SDK configuration, the SDK executes these two stages before and after you [identify a context](/docs/sdk/features/identify). Only available for client-side SDKs.</td>
    </tr>

    <tr>
      <td>Track</td>
      <td>`afterTrack`</td>
      <td>When you include a hook in your SDK configuration, the SDK executes this stage after you [send a custom event](/docs/sdk/features/events).</td>
    </tr>
  </tbody>
</table>

Not all SDKs support all of these series. In particular, the identify series is only available for client-side SDKs. Details about how to add hooks to each SDK are available in the SDK-specific sections below.

* [Server-side SDKs](#server-side-sdks)
* [Client-side SDKs](#client-side-sdks)

## Server-side SDKs

This feature is available in the following SDKs:

* [.NET (server-side)](#net-server-side)
* [Go](#go)
* [Java](#java)
* [Node.js (server-side)](#node-js-server-side)
* [PHP](#php)
* [Python](#python)
* [Ruby](#ruby)

### .NET (server-side)

<Accordion title="Expand .NET (server-side) code sample">
  To use hook functionality with the .NET (server-side) SDK, first import the `LaunchDarkly.Sdk.Server.Hooks` namespace. Then, define a new hook. This class must derive from the [`Hook`](https://launchdarkly.github.io/dotnet-core/pkgs/sdk/server/api/LaunchDarkly.Sdk.Server.Hooks.Hook.html) class and override its methods. Finally, reference the hook in the configuration options when you initialize the SDK client.

  Here's how:

  <CodeGroup>
    ```csharp title=".NET (server-side), v8.4+" maxLines=0 expandable lines wrap theme={null}
    using LaunchDarkly.Sdk.Server.Hooks;

    public class ExampleHook : Hook {

      public ExampleHook() : base("example-hook") { }

      // Implement at least one of `BeforeEvaluation`, `AfterEvaluation`

      // `BeforeEvaluation` is called during the execution of a variation method
      // before the flag value has been determined

      // `AfterEvaluation` is called during the execution of a variation method
      // after the flag value has been determined

    }

    var exampleHook = new ExampleHook();

    var config = Configuration.Builder("YOUR_SDK_KEY")
      .Hooks(Components.Hooks()
        .Add(exampleHook)
      ).Build();

    var client = new LdClient(config);
    ```
  </CodeGroup>

  To learn more, read [`Hooks`](https://launchdarkly.github.io/dotnet-core/pkgs/sdk/server/api/LaunchDarkly.Sdk.Server.Hooks.html).
</Accordion>

### Go

<Accordion title="Expand Go code sample">
  To use hook functionality with the Go SDK, first import the `ldhooks` package. Then, define a new hook. It must implement the [`Hook`](https://pkg.go.dev/github.com/launchdarkly/go-server-sdk/v7@v7.4.0/ldhooks#Hook) interface.  Finally, reference the hook in the configuration options when you initialize the SDK client.

  Here's how:

  <CodeGroup>
    ```go title="Go SDK, v7.4+" maxLines=0 expandable lines wrap theme={null}
    import (
      ld "github.com/launchdarkly/go-server-sdk/v7"
      "github.com/launchdarkly/go-server-sdk/v7/ldhooks"
    )

    type exampleHook struct {
      ldhooks.Unimplemented
      metadata ldhooks.Metadata
    }

    func (e exampleHook) Metadata() ldhooks.Metadata {
      return e.metadata
    }

    // Implement at least one of `BeforeEvaluation`, `AfterEvaluation`

    // `BeforeEvaluation` is called during the execution of a variation method
    // before the flag value has been determined

    // `AfterEvaluation` is called during the execution of a variation method
    // after the flag value has been determined

    func newExampleHook() exampleHook {}

    var config ld.Config

    client, _ = ld.MakeCustomClient("YOUR_SDK_KEY",
      ld.Config{
        Hooks: []ldhooks.Hook{newExampleHook()},
      }, 5*time.Second)

    ```
  </CodeGroup>

  To learn more, read [`Hook`](https://pkg.go.dev/github.com/launchdarkly/go-server-sdk/v7@v7.4.0/ldhooks#Hook).
</Accordion>

### Java

<Accordion title="Expand Java code sample">
  To use hook functionality with the Java SDK, first define a new hook. This class must implement the [`Hook`](https://launchdarkly.github.io/java-core/lib/sdk/server/com/launchdarkly/sdk/server/integrations/Hook.html) abstract class. Then, reference the hook in the configuration options when you initialize the SDK client.

  Here's how:

  <CodeGroup>
    ```java title="Java SDK, v7.4+" maxLines=0 expandable lines wrap theme={null}
    import com.launchdarkly.sdk.server.integrations.Hook;

    class ExampleHook extends Hook {

      public ExampleHook(String name) {
        super(name);
      }

      // Implement at least one of `beforeEvaluation`, `afterEvaluation`

      // `beforeEvaluation` is called during the execution of a variation method
      // before the flag value has been determined

      // `afterEvaluation` is called during the execution of a variation method
      // after the flag value has been determined
    }

    ExampleHook exampleHook = new ExampleHook("example-hook");

    LDConfig config = new LDConfig.Builder()
        .hooks(
            Components.hooks().setHooks(Collections.singletonList(exampleHook)))
        .build();

    LDClient client = new LDClient("YOUR_SDK_KEY", config);
    ```
  </CodeGroup>

  To learn more, read [`Hook`](https://launchdarkly.github.io/java-core/lib/sdk/server/com/launchdarkly/sdk/server/integrations/Hook.html).
</Accordion>

### Node.js (server-side)

<Accordion title="Expand Node.js (server-side) code sample">
  To use hook functionality with the Node.js (server-side) SDK, first define a new hook. This class must extend the [`Hook`](https://launchdarkly.github.io/js-core/packages/shared/sdk-server/docs/interfaces/integrations.Hook.html) interface. Then, reference the hook in the configuration options when you initialize the SDK client.

  Here's how:

  <CodeGroup>
    ```ts title="Node.js (server-side) SDK, v9.3+" maxLines=0 expandable lines wrap theme={null}
    export class ExampleHook implements integrations.Hook {

      getMetadata() {
        return { name: 'Example hook'}
      }

      // Implement at least one of `beforeEvaluation`, `afterEvaluation`

      // `beforeEvaluation` is called during the execution of a variation method
      // before the flag value has been determined

      // `afterEvaluation` is called during the execution of a variation method
      // after the flag value has been determined
    }

    const options: ld.LDOptions = {
      hooks: [new ExampleHook()]
    };

    const client = ld.init('YOUR_SDK_KEY', options);
    ```
  </CodeGroup>

  You can also add a hook to an existing client using the `addHook` method:

  <CodeGroup>
    ```ts title="Node.js (server-side) SDK, v9.3+" lines wrap theme={null}

    const client = ld.init('YOUR_SDK_KEY', options);
    client.addHook(new ExampleHook());

    ```
  </CodeGroup>

  To learn more, read [`Hook`](https://launchdarkly.github.io/js-core/packages/shared/sdk-server/docs/interfaces/integrations.Hook.html).
</Accordion>

### PHP

<Accordion title="Expand PHP code sample">
  To use hook functionality with the PHP SDK, first define a new hook. This class must extend the `LaunchDarkly\Hooks\Hook` abstract class and implement `getMetadata`. Then, reference the hook in the configuration options when you initialize the SDK client.

  Here's how:

  <CodeGroup>
    ```php title="PHP, v6.8+" maxLines=0 expandable lines wrap theme={null}
    use LaunchDarkly\Hooks\EvaluationSeriesContext;
    use LaunchDarkly\Hooks\Hook;
    use LaunchDarkly\Hooks\Metadata;
    use LaunchDarkly\Hooks\TrackSeriesContext;
    use LaunchDarkly\EvaluationDetail;
    use LaunchDarkly\LDClient;

    class ExampleHook extends Hook
    {
        public function getMetadata(): Metadata
        {
            return new Metadata('example-hook');
        }

        // Implement at least one of `beforeEvaluation`, `afterEvaluation`, or `afterTrack`

        // `beforeEvaluation` is called during the execution of a variation method
        // before the flag value has been determined

        // `afterEvaluation` is called during the execution of a variation method
        // after the flag value has been determined

        // `afterTrack` is called after a custom event has been enqueued by `track`
    }

    $client = new LDClient('YOUR_SDK_KEY', [
        'hooks' => [new ExampleHook()],
    ]);
    ```
  </CodeGroup>

  You can also add a hook to an existing client using the `addHook` method:

  <CodeGroup>
    ```php title="PHP, v6.8+" lines wrap theme={null}
    $client = new LDClient('YOUR_SDK_KEY');
    $client->addHook(new ExampleHook());
    ```
  </CodeGroup>

  To learn more, read the [SDK API documentation](https://launchdarkly.github.io/php-server-sdk/).
</Accordion>

### Python

<Accordion title="Expand Python code sample">
  To use hook functionality with the Python SDK, first define a new hook. This class must inherit from [`ldclient.hook.Hook`](https://launchdarkly-python-sdk.readthedocs.io/en/latest/api-main.html#ldclient.hook.Hook). Then, reference the hook in the configuration options when you initialize the SDK client.

  Here's how:

  <CodeGroup>
    ```python title="Python, v9.4+" maxLines=0 expandable lines wrap theme={null}
    import ldclient

    from ldclient import Config
    from ldclient.hook import Hook, Metadata


    class ExampleHook(Hook):
        @property
        def metadata(self) -> Metadata:
            return Metadata(name="example-hook")

        # Implement at least one of `before_evaluation`, `after_evaluation`

        # `before_evaluation` is called during the execution of a variation method
        # before the flag value has been determined

        # `after_evaluation` is called during the execution of a variation method
        # after the flag value has been determined


    example_hook = ExampleHook()

    config = Config("YOUR_SDK_KEY", hooks=[example_hook])

    ldclient.set_config(config=config)
    client = ldclient.get()
    ```
  </CodeGroup>

  You can also add a hook to an existing client using the `add_hook` method:

  <CodeGroup>
    ```python title="Python, v9.4+" lines wrap theme={null}
    ldclient.set_config(config=config)
    client = ldclient.get()

    client.add_hook(example_hook)
    ```
  </CodeGroup>

  To learn more, read [`ldclient.hook`](https://launchdarkly-python-sdk.readthedocs.io/en/latest/api-main.html#module-ldclient.hook).

  If you are working with forking processes, any configuration that you provide to the SDK must survive the forking process independently. We recommend that you add any hooks after a `postfork()` call, unless you are certain they can survive the forking process. To learn more, read [Initialize the client](/docs/sdk/server-side/python#initialize-the-client) and [`ldclient.postfork`](https://launchdarkly-python-sdk.readthedocs.io/en/latest/api-main.html#ldclient.client.LDClient.postfork).
</Accordion>

### Ruby

<Accordion title="Expand Ruby code sample">
  To use hook functionality with the Ruby SDK, first define a new hook. This class must include the [`Hooks`](https://launchdarkly.github.io/ruby-server-sdk/LaunchDarkly/Interfaces/Hooks/Hook.html) mixin. Then, reference the hook in the configuration options when you initialize the SDK client.

  Here's how:

  <CodeGroup>
    ```ruby title="Ruby, v8.4+" maxLines=0 expandable lines wrap theme={null}
    require 'ldclient-rb'

    class ExampleHook
      include LaunchDarkly::Interfaces::Hooks::Hook

      def metadata
        LaunchDarkly::Interfaces::Hooks::Metadata.new('example-hook')
      end

      # Implement at least one of `before_evaluation`, `after_evaluation`

      # `before_evaluation` is called during the execution of a variation method
      # before the flag value has been determined

      # `after_evaluation` is called during the execution of a variation method
      # after the flag value has been determined
    end

    example_hook = ExampleHook.new

    config = LaunchDarkly::Config.new(hooks: [example_hook])

    client = LaunchDarkly::LDClient.new("YOUR_SDK_KEY", config)
    ```
  </CodeGroup>

  You can also add a hook to an existing client using the `add_hook` method:

  <CodeGroup>
    ```ruby title="Ruby, v8.4+" lines wrap theme={null}
    client = LaunchDarkly::LDClient.new("YOUR_SDK_KEY", config)

    client.add_hook(example_hook)

    ```
  </CodeGroup>

  To learn more, read [`Hooks`](https://launchdarkly.github.io/ruby-server-sdk/LaunchDarkly/Interfaces/Hooks.html).

  If you are working with forking processes, any configuration that you provide to the SDK must survive the forking process independently. We recommend that you add any hooks after a `postfork()` call, unless you are certain they can survive the forking process. To learn more, read [Initialize the client](/docs/sdk/server-side/ruby#initialize-the-client) and [`postfork`](https://launchdarkly.github.io/ruby-server-sdk/LaunchDarkly/LDClient.html#postfork-instance_method).
</Accordion>

## Client-side SDKs

This feature is available in the following SDKs:

* [Android](#android)
* [iOS](#ios)
* [JavaScript](#javascript)
* [React Native](#react-native)
* [Vue](#vue): The Vue SDK relies on the JavaScript SDK for this functionality.

### Android

<Accordion title="Expand Android code sample">
  To use hook functionality with the Android SDK, first define a new hook. This class must extend the [`Hook`](https://launchdarkly.github.io/android-client-sdk/com/launchdarkly/sdk/android/integrations/Hook.html) class. Then, reference the hook in the configuration options when you initialize the SDK client.

  Here's how:

  <CodeGroup>
    ```java title="Android SDK, v5.8+" maxLines=0 expandable lines wrap theme={null}

    public class ExampleHook extends Hook {

      public ExampleHook(String name) {
        super(name);
      }

      // Implement at least one of:
      //
      // * `beforeEvaluation` - called during the execution of a variation method
      // before the flag value has been determined
      //
      // * `afterEvaluation` - called during the execution of a variation method
      // after the flag value has been determined
      //
      // * `beforeIdentify` - called during the execution of the identify process
      // before the operation completes, but after any context modifications are performed
      //
      // * `afterIdentify` - called during the execution of the identify process
      // after the operation completes
      //
      // * `afterTrack` - called during the execution of the track process
      // after the event has been enqueued
    }

    List<Hook> hookList = new ArrayList<>();
    ExampleHook exampleHook = new ExampleHook("Example hook");
    hookList.add(exampleHook);

    LDConfig ldConfig = new LDConfig.Builder(AutoEnvAttributes.Enabled)
        .mobileKey("example-mobile-key")
        .hooks(
          Components.hooks()
            .setHooks(hookList)
        )
        .build();

    LDContext context = LDContext.create("example-context-key");

    LDClient client = LDClient.init(this.getApplication(), ldConfig, context, 0);

    ```
  </CodeGroup>

  You can also add a hook to an existing client using the `setHooks` method:

  <CodeGroup>
    ```java title="Android SDK, v5.8+" lines wrap theme={null}
    List<Hook> hookList = new ArrayList<>();
    ExampleHook exampleHook = new ExampleHook("Example hook");
    hookList.add(exampleHook);

    client.addHook(exampleHook);

    ```
  </CodeGroup>

  To learn more, read [`Hook`](https://launchdarkly.github.io/android-client-sdk/com/launchdarkly/sdk/android/integrations/Hook.html) and [`HooksConfigurationBuilder`](https://launchdarkly.github.io/android-client-sdk/com/launchdarkly/sdk/android/integrations/HooksConfigurationBuilder.html).
</Accordion>

### iOS

<Accordion title="Expand iOS code sample">
  To use hook functionality with the iOS SDK, first define a new hook. This class must use the [`Hook`](https://launchdarkly.github.io/ios-client-sdk/Protocols/Hook.html) protocol. Then, reference the hook in the configuration options when you initialize the SDK client.

  Here's how:

  <CodeGroup>
    ```swift title="iOS, v9.7.2+ (Swift)" maxLines=0 expandable lines wrap theme={null}
    import LaunchDarkly

    class ExampleHook: Hook {
        func metadata() -> Metadata {
            return Metadata(name: "example-hook")
        }

        /// Implement at least one of `beforeEvaluation`, `afterEvaluation`

        /// beforeEvaluation is called during the execution of a variation method
        /// before the flag value has been determined

        /// afterEvaluation is called during the execution of a variation method
        /// after the flag value has been determined
    }

    let exampleHook = ExampleHook()

    var config = LDConfig(
      mobileKey: "example-mobile-key",
      autoEnvAttributes: .enabled
    )
    config.hooks = [exampleHook]

    let context = try! LDContextBuilder(key: "example-context-key").build().get()

    LDClient.start(config: config, context: context, startWaitSeconds: 5) { timedOut in
        if timedOut {
            /// Client may not have the most recent flags for the configured context
        } else {
            /// Client has received flags for the configured context
        }
    }
    ```
  </CodeGroup>

  To learn more, read [`Hook`](https://launchdarkly.github.io/ios-client-sdk/Protocols/Hook.html).
</Accordion>

### JavaScript

<Accordion title="Expand JavaScript code sample">
  To use hook functionality with the JavaScript SDK, first define a new hook. This class must extend the [`Hook`](https://launchdarkly.github.io/js-client-sdk/interfaces/Hook.html) interface. Then, reference the hook in the configuration options when you initialize the SDK client.

  Here's how:

  <CodeGroup>
    ```js title="JavaScript SDK, v4.x" maxLines=0 expandable lines wrap theme={null}
    export class ExampleHook implements Hook {

      getMetadata() {
        return { name: 'Example hook'}
      }

      // Implement at least one of:
      //
      // * `beforeEvaluation` - called during the execution of a variation method
      // before the flag value has been determined
      //
      // * `afterEvaluation` - called during the execution of a variation method
      // after the flag value has been determined
      //
      // * `beforeIdentify` - called during the execution of the identify process
      // before the operation completes, but after any context modifications are performed
      //
      // * `afterIdentify` - called during the execution of the identify process
      // after the operation completes
      //
      // * `afterTrack` - called during the execution of the track process
      // after the event has been enqueued
    }

    const options = {
      hooks: [new ExampleHook()]
    };

    const client = LDClient.initialize('example-client-side-id', options);
    ```

    ```js title="JavaScript SDK, v3.6+" maxLines=0 expandable lines wrap theme={null}
    export class ExampleHook implements Hook {

      getMetadata() {
        return { name: 'Example hook'}
      }

      // Implement at least one of:
      //
      // * `beforeEvaluation` - called during the execution of a variation method
      // before the flag value has been determined
      //
      // * `afterEvaluation` - called during the execution of a variation method
      // after the flag value has been determined
      //
      // * `beforeIdentify` - called during the execution of the identify process
      // before the operation completes, but after any context modifications are performed
      //
      // * `afterIdentify` - called during the execution of the identify process
      // after the operation completes
      //
      // * `afterTrack` - called during the execution of the track process
      // after the event has been enqueued
    }

    const options = {
      hooks: [new ExampleHook()]
    };

    const client = LDClient.initialize('example-client-side-id', context, options);
    ```
  </CodeGroup>

  You can also add a hook to an existing client using the `addHook` method:

  <CodeGroup>
    ```js title="JavaScript SDK, v4.x" lines wrap theme={null}

    const client = LDClient.initialize('example-client-side-id', options);
    client.addHook(new ExampleHook());

    ```

    ```js title="JavaScript SDK, v3.6+" lines wrap theme={null}

    const client = LDClient.initialize('example-client-side-id', context, options);
    client.addHook(new ExampleHook());

    ```
  </CodeGroup>

  To learn more, read [`Hook`](https://launchdarkly.github.io/js-core/packages/sdk/browser/docs/interfaces/Hook.html).
</Accordion>

### React Native

<Accordion title="Expand React Native code sample">
  To use hook functionality with the React Native SDK, first define a new hook. This class must extend the [`Hook`](https://launchdarkly.github.io/js-core/packages/sdk/react-native/docs/interfaces/Hook.html) interface. Then, reference the hook in the configuration options when you initialize the SDK client.

  Here's how:

  <CodeGroup>
    ```ts title="React Native SDK, v10+" expandable lines wrap theme={null}
    export class ExampleHook implements Hook {

      getMetadata() {
        return { name: 'Example hook'}
      }

      // Implement at least one of:
      //
      // * `beforeEvaluation` - called during the execution of a variation method
      // before the flag value has been determined
      //
      // * `afterEvaluation` - called during the execution of a variation method
      // after the flag value has been determined
      //
      // * `beforeIdentify` - called during the execution of the identify process
      // before the operation completes, but after any context modifications are performed
      //
      // * `afterIdentify` - called during the execution of the identify process
      // after the operation completes
      //
      // * `afterTrack` - called during the execution of the track process
      // after the event has been enqueued
    }

    const options: LDOptions = {
      hooks: [new ExampleHook()]
    };

    const client = new ReactNativeLDClient('example-mobile-key', AutoEnvAttributes.Enabled, options);
    ```
  </CodeGroup>

  You can also add a hook to an existing client using the `addHook` method:

  <CodeGroup>
    ```ts title="React Native SDK, v10+" lines wrap theme={null}

    const client = new ReactNativeLDClient('example-mobile-key', AutoEnvAttributes.Enabled, options);
    client.addHook(new ExampleHook());

    ```
  </CodeGroup>

  To learn more, read [`Hook`](https://launchdarkly.github.io/js-core/packages/sdk/react-native/docs/interfaces/Hook.html).
</Accordion>

### Vue

<Accordion title="Expand Vue code sample">
  The Vue SDK relies on the [JavaScript SDK](#javascript) for hooks. Define a hook that implements the `Hook` interface, then set the `hooks` option in `ldOptions` when you install the plugin or create a provider.

  Here's how:

  <CodeGroup>
    ```ts title="Vue SDK v3.0" lines wrap theme={null}
    import { createApp } from 'vue'
    import { LDVuePlugin, type Hook } from '@launchdarkly/vue-client-sdk'
    import App from './App.vue'

    class ExampleHook implements Hook {
      getMetadata() {
        return { name: 'Example hook' }
      }

      // Implement at least one of:
      // `beforeEvaluation`, `afterEvaluation`, `beforeIdentify`,
      // `afterIdentify`, or `afterTrack`.
    }

    createApp(App)
      .use(LDVuePlugin, {
        clientSideID: 'example-client-side-id',
        context: { kind: 'user', key: 'example-context-key' },
        ldOptions: {
          hooks: [new ExampleHook()]
        }
      })
      .mount('#app')
    ```
  </CodeGroup>

  You can also add a hook later. Retrieve the client with `useLDClient()` and call `addHook()`.

  To learn more about defining a hook, read [JavaScript](#javascript).
</Accordion>
