> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.getunleash.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.getunleash.io/_mcp/server.

# Flutter SDK

> Set up the Unleash Flutter SDK to evaluate feature flags in Flutter apps with context, variants, events, and bootstrap.

The Unleash Flutter SDK lets you evaluate feature flags in Flutter applications. It connects to Unleash or [Unleash Edge](/unleash-edge) to fetch evaluated flags for a given [Unleash context](/concepts/unleash-context).

You can use this SDK with [Unleash Enterprise](https://www.getunleash.io/pricing) or [Unleash Open Source](https://github.com/Unleash/unleash).

For an overview of how Unleash SDKs work, including offline behavior, feature compatibility across SDKs, and default refresh and metrics intervals, refer to the [SDK overview](/sdks).

## Installation

```
flutter pub add unleash_proxy_client_flutter
```

## Initialization

Configure the client according to your needs. The following example provides only the required options. Refer to [configuration options](#configuration-options) for the full list.

Set `url` to the `/api/frontend` endpoint of your Unleash instance or your [Unleash Edge](/unleash-edge) instance. Set `clientKey` to a [frontend API token](/concepts/api-tokens-and-client-keys#frontend-tokens).

```dart
import 'package:unleash_proxy_client_flutter/unleash_proxy_client_flutter.dart';

final unleash = UnleashClient(
    url: Uri.parse('https://<your-unleash-instance>/api/frontend'),
    clientKey: '<your-client-side-token>',
    appName: 'my-app');
unleash.start();
```

### Check if the SDK is ready

You should wait for the client's `ready` or `initialized` events before you start working with it. Before it's ready, the client might not report the correct state for your features.

```dart
unleash.on('ready', (_) {
    if (unleash.isEnabled('flutter.demo')) {
      print('flutter.demo is enabled');
    } else {
      print('flutter.demo is disabled');
    }
});
```

The difference between the events is [explained below](#events).

## Check flags

Once the client is ready, you can start checking features in your application. Use the `isEnabled` method to check the state of any feature you want:

```dart
unleash.isEnabled('flutter.demo');
```

You can use the `getVariant` method to get the variant of an **enabled feature that has variants**. If the feature is disabled or if it has no variants, then you will get back the [**disabled variant**](/concepts/feature-flag-variants#the-disabled-variant)

```dart
final variant = unleash.getVariant('flutter.demo');

if (variant.name == 'blue') {
 // something with variant blue...
}
```

You can also access the payload associated with the variant:

```dart
final variant = unleash.getVariant('flutter.demo');
final payload = variant.payload;

if (payload != null) {
  // do something with the payload
  // print(payload "${payload.type} ${payload.value}");
}
```

### Unleash context

The [Unleash context](/concepts/unleash-context) holds properties such as user ID, session ID, and custom fields that drive flag evaluation, including strategy targeting, constraints, and stickiness. To update and configure the Unleash context in this SDK, use the `updateContext`, `setContextField`, and `setContextFields` methods.

The context you set in your app will be passed along to Unleash Edge or the Frontend API as query parameters for feature evaluation.

The `updateContext` method will replace the entire
(mutable part) of the Unleash context with the data that you pass in.

The `setContextField` method only acts on the property that you choose. It does not affect any other properties of the Unleash context.

The `setContextFields` method only acts on the properties that you choose. It does not affect any other properties of the Unleash context.

```dart
// Used to set the context fields, shared with the Unleash Edge. This
// method will replace the entire (mutable part) of the Unleash Context.
unleash.updateContext(UnleashContext(userId: '1233'));

// Used to update a single field on the Unleash Context.
unleash.setContextField('userId', '4141');

// Used to update multiple context fields on the Unleash Context.
unleash.setContextFields({'userId': '4141'});
```

## Configuration options

The Unleash SDK takes the following options:

| option            | required | default                            | description                                                                                                                                                                                                                                                       |
| ----------------- | -------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| url               | yes      | n/a                                | The Unleash Frontend API URL to connect to. E.g.: `https://eu.app.unleash-hosted.com/demo/api/frontend`                                                                                                                                                           |
| clientKey         | yes      | n/a                                | The Frontend Token to be used                                                                                                                                                                                                                                     |
| appName           | yes      | n/a                                | The name of the application using this SDK. Will be used as part of the metrics sent to Unleash Edge/Frontend API. Will also be part of the Unleash Context.                                                                                                      |
| refreshInterval   | no       | 30                                 | How often, in seconds, the SDK should check for updated toggle configuration. If set to 0 will disable checking for updates                                                                                                                                       |
| disableRefresh    | no       | false                              | If set to true, the client will not check for updated toggle configuration                                                                                                                                                                                        |
| metricsInterval   | no       | 30                                 | How often, in seconds, the SDK should send usage metrics back to Unleash                                                                                                                                                                                          |
| disableMetrics    | no       | false                              | Set this option to `true` if you want to disable usage metrics                                                                                                                                                                                                    |
| storageProvider   | no       | `SharedPreferencesStorageProvider` | Allows you to inject a custom storeProvider                                                                                                                                                                                                                       |
| bootstrap         | no       | `null`                             | Allows you to bootstrap the cached feature toggle configuration.                                                                                                                                                                                                  |
| bootstrapOverride | no       | `true`                             | Should the bootstrap automatically override cached data in the local-storage. Will only be used if bootstrap is not an empty array.                                                                                                                               |
| headerName        | no       | `Authorization`                    | Provides possibility to specify custom header that is passed to Unleash / Unleash Edge with the `clientKey`                                                                                                                                                       |
| customHeaders     | no       | `{}`                               | Additional headers to use when making HTTP requests to the Unleash. In case of name collisions with the default headers, the `customHeaders` value will be used.                                                                                                  |
| impressionDataAll | no       | `false`                            | Allows you to trigger "impression" events for **all** `getToggle` and `getVariant` invocations. This is particularly useful for "disabled" feature flags that are not visible to frontend SDKs.                                                                   |
| fetcher           | no       | `http.get`                         | Allows you to define your own **fetcher**. Can be used to add certificate pinning or additional http behavior.                                                                                                                                                    |
| poster            | no       | `http.post`                        | Allows you to define your own **poster**. Can be used to add certificate pinning or additional http behavior.                                                                                                                                                     |
| experimental      | no       | `null`                             | Enabling optional experimentation. `togglesStorageTTL` : How long (Time To Live), in seconds, the toggles in storage are considered valid and should not be fetched on start. If set to 0 will disable expiration checking and will be considered always expired. |

## Events

The client is also an event emitter. This means that your code can subscribe to updates from the client.
This is a neat way to update your app when toggle state updates.

```dart
unleash.on('update', (_) {
    final myToggle = unleash.isEnabled('flutter.demo');
    //do something useful
});
```

The SDK emits the following events:

* **error** - emitted when an error occurs on init, or when fetch function fails, or when fetch receives a non-ok response object. The error object is sent as payload.
* **initialized** - emitted after the SDK has read local cached data in the storageProvider.
* **ready** - emitted after the SDK has successfully started and performed the initial fetch towards Unleash.
* **update** - emitted every time the Unleash returns a new feature toggle configuration. The SDK will emit this event as part of the initial fetch from the SDK.

Please remember that you should always register your event listeners before your call `unleash.start()`. If you register them after you have started the SDK you risk losing important events.

## Session ID

You may provide a custom session id via the "context". If you do not provide a sessionId this SDK will create a random session id, which will also be stored in the provided storage. By always having a consistent sessionId available ensures that even "anonymous" users will get a consistent experience when feature flags are evaluated, in combination with a gradual (percentage based) rollout.

## Stop the client

You can stop the Unleash client by calling the `stop` method. Once the client has been stopped, it will no longer check for updates or send metrics to the server.

A stopped client *can* be restarted.

```dart
unleash.stop();
```

## Bootstrap

You can bootstrap the SDK with your own flag configuration to avoid an API call on startup. Add a `bootstrap` attribute when you create a new `UnleashClient`.
There's also a `bootstrapOverride` attribute which by default is `true`.

```dart
final unleash = UnleashClient(
    url: Uri.parse('https://app.unleash-hosted.com/demo/api/flutter'),
    clientKey: 'token-123',
    appName: 'my-app',
    bootstrapOverride: false,
    bootstrap: {
    'demoApp.step4': ToggleConfig(
        enabled: true,
        impressionData: false,
        variant: Variant(enabled: true, name: 'blue'))
});
```

* If `bootstrapOverride` is `true` (by default), any local cached data will be overridden with the bootstrap specified.
* If `bootstrapOverride` is `false` any local cached data will not be overridden unless the local cache is empty.

## Manage your own refresh mechanism

You can opt out of the Unleash feature flag auto-refresh mechanism and metrics update by settings the `refreshInterval` and/or `metricsInterval` options to `0`.
In this case, it becomes your responsibility to call `updateToggles` and/or `sendMetrics` methods.

## Skip fetching flags on start

This is an experimental feature and may change in future releases.

If you run multiple clients that share the same storage provider (for example, the default `SharedPreferencesStorageProvider`), you can skip fetching flags on start for all but one client. Set `togglesStorageTTL` to a non-zero value to reuse cached flags that are still within the TTL window.

In the following example, flags in storage are considered valid for 60 seconds and are not fetched on start if they already exist. Set `togglesStorageTTL` to a value greater than `refreshInterval`.

```dart
final anotherUnleash = UnleashClient(
    // ...
    experimental: const ExperimentalConfig(togglesStorageTTL: 60)
);
```