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

# Configure a Flag

> Create your first feature flag, define its schema and variants, force a variant for testing, and verify resolution using the resolve tester.

export const YouTubeVideo = ({src, title}) => {
  return <Frame>
      <iframe className="w-full aspect-video rounded-xl" src={src} title={title} allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
    </Frame>;
};

This tutorial shows you how to configure a flag that controls the design of a
header of a website.

The tutorial consists of the following steps:

1. [Create a flag](#create-a-flag) for the header design, and define its schema.
2. [Use the flag](#use-the-flag) in the website to control the header.
3. [Create variants](#create-variants) of the header.
4. [Force a variant for a user](#force-a-variant-for-a-user) to test a specific
   variant.
5. [Test resolving the flag](#resolve-tester) with an evaluation context.

This page targets the following audience:

* Anyone who wants to set up a flag and understand how to use it.

Before you begin:

* You need to have a Portal instance with Confidence Flags Plugin turned on.

## Resolve in a Way That Fits Your Application

You can resolve a feature flag in two ways. Use
Confidence's managed resolver or use a local resolver that you host.

All feature flags must have at least one associated client. A
client can, for example, be a backend service or a website. The clients use
flags to serve different experiences. To resolve flags, a client needs to
authenticate with Confidence Flags using a client credential.

<Info>
  Confidence Flags comes with at least one client by default with the same name
  as your Portal account. You can use this client if you want, or create a more
  specific client for web feature flags to use for the flag you create in this
  quickstart.
</Info>

## Create a Flag

Flags let Confidence Flags control the behavior of your application.
For example, use a flag to control which machine learning model serves a recommendation, the number
and size of tiles on a page, or a call to action message and its position on a sign-up page.
For this tutorial, create a flag that controls the color and size of a header.

To create the flag, follow these steps.

1. Go to Portal and select **Confidence flags** on the left sidebar.
2. Click **+ Create** to create a new flag.
3. Name the flag `header-redesign`.
4. Select the existing client in the clients dialog (or create a new one).

In the last step, you associated the flag with a specific client. This means
that only **this client** can resolve the `header-redesign` flag. Making it
possible to limit which flags are available to which clients is beneficial from
multiple perspectives. For one, it allows you to limit what flags are available
to clients that run in uncontrolled environments such as mobile phones, or
service-side web apps. Moreover, if you resolve flags in batch, for example at
app start, limiting the resolving to only the relevant flags saves resources.

Next, you define the schema of the flag. The value of a flag is not just a
single value, but rather a key-value map of properties. To avoid errors and to
make it easier to work with flags, Confidence Flags asks you to define a schema for
the flag value. The schema describe the shape of the flag value, by defining
properties and their data types.

In this tutorial, your flag controls the design of a header on a website.
The design consists of color and size, so your flag needs to set two properties: `color` and `size`.

1. Click **Edit schema**.
2. Click **Add property** and select **string**.
3. Name the property `color`.
4. Click **Add property** and select **int**.
5. Name the property `size`.

You can configure or edit your schema by opening it on the right sidebar.

Now that you defined the schema, you can create variants that have specific
values for the `color` and `size` properties.

## Create Variants

The two variants you want to create for the header redesign are black in size
14, and blue in size 16. To do that, follow these steps.

1. Click **+ Create variant** and name it `default-style`.
2. Enter `black` as the value for `color`, and `14` as the size.
3. Click **Save**.
4. Click **+ Create variant** and name it `new-style`.
5. Enter `blue` as the value for `color`, and `16` as the size.

The two variants are now created, but they're not yet reaching any user.
To test your flag, use an override rule next.

## Use the Flag

Each flag in Confidence Flags has code snippets on how to resolve the flag using the various SDKs. To
view these code snippets:

1. Go to **Confidence flags** on the left sidebar and select your flag.
2. Click on **Code snippets** on the overview page of the flag.
3. Select your client, like the **Web client** created in an earlier step, from the client dropdown list. Select
   the credential from the credential dropdown list.
4. Choose the SDK and language that you want to resolve the flag with.
5. Follow the instructions for installing the SDK.
6. Follow the instructions for resolving the flags.

Next, see the code you need for resolving the `header-redesign` flag created earlier in this
guide. When resolving a flag into a value, you specify a default value. The default value applies if a user doesn't match or
isn't assigned by a rule. The following code sets the default value to the `color` green, and `size` 10.

### Install Dependencies

You first need to install the necessary dependencies.

<Tabs>
  <Tab title="Javascript">`bash yarn add @spotify-confidence/sdk `</Tab>

  <Tab title="Python">`bash pip install spotify-confidence-sdk `</Tab>

  <Tab title="Java">
    ```xml {{ title: 'Java' }} theme={"theme":{"light":"github-light","dark":"dracula"}}
    // Add to pom.xml
    // Replace LATEST by the latest version of the SDK.
    <dependency>
        <groupId>com.spotify.confidence</groupId>
        <artifactId>sdk-java</artifactId>
        <version><LATEST></version>
    </dependency>
    ```
  </Tab>

  <Tab title="Go">
    ````bash {{ title: 'Go' }} theme={"theme":{"light":"github-light","dark":"dracula"}}
    go get github.com/spotify/confidence-sdk-go ```
    </Tab>

    <Tab title="iOS">
    ```bash {{ title: 'iOS' }}
    // When using Swift Package Manager, add the following to Package.swift
    // Replace LATEST by the latest version of the SDK
    .package(url: "git@github.com:spotify/confidence-sdk-swift.git", from: "<LATEST>")
    .product(name: "Confidence", package: "confidence-sdk-swift")
    ````
  </Tab>

  <Tab title="Android">
    ```bash {{ title: 'Android' }} theme={"theme":{"light":"github-light","dark":"dracula"}}
    // Replace LATEST by the latest version of the SDK
    implementation("com.spotify.confidence:confidence-sdk-android:<LATEST>")
    ```
  </Tab>
</Tabs>

### Initialize the Confidence Flags SDK

With dependencies installed, you can now construct a Confidence object for your platform.
You only need to do this once, preferably on app startup.

It's suggested that you configure the Confidence SDK to show logs on all levels when
first integrating to understand how the SDK works. After you've got the feel for it,
limit logging to `WARN` and above.

<CodeGroup>
  ```javascript Javascript (Web) theme={"theme":{"light":"github-light","dark":"dracula"}}
  import { Confidence } from '@spotify-confidence/sdk';

  const confidence = Confidence.create({
    clientSecret: '<CLIENT_SECRET>',
    environment: 'client',
    timeout: 1000,
    logger: console,
  });

  // Set the context that is relevant for your flag, like the user ID.
  confidence.setContext({ user_id: 'user-test-id' });
  confidence.setContext({ plan: 'premium' });
  ```

  ```javascript Javascript (Server) theme={"theme":{"light":"github-light","dark":"dracula"}}
  import { Confidence } from '@spotify-confidence/sdk';

  const confidence = Confidence.create({
    clientSecret: '<CLIENT_SECRET>',
    environment: 'server',
    timeout: 1000,
    logger: console,
  });
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"dracula"}}
  from confidence.confidence import Confidence

  confidence = Confidence("<CLIENT_SECRET>")

  ```

  ```java Java theme={"theme":{"light":"github-light","dark":"dracula"}}
  import com.spotify.confidence.Confidence;

  Confidence confidence = Confidence.builder("<CLIENT_SECRET>").build();
  ```

  ```go Go theme={"theme":{"light":"github-light","dark":"dracula"}}
  import (
  c "github.com/spotify/confidence-sdk-go/pkg/confidence"
  )
  confidence := c.NewConfidenceBuilder().SetAPIConfig(c.APIConfig{APIKey: "<CLIENT_SECRET>"}).Build()
  ```

  ```swift iOS (Swift) theme={"theme":{"light":"github-light","dark":"dracula"}}
  import Confidence

  let confidence = Confidence.Builder(clientSecret: "<CLIENT_SECRET>", loggerLevel: .DEBUG)
  // Setup the context that is relevant for your flag, like the user ID.
  .withContext(initialContext: [
  "user_id": ConfidenceValue.init(string: "user-test-id"),
  "plan": ConfidenceValue.init(string: "premium")
  ])
  .build()
  try await confidence.fetchAndActivate()

  ```

  ```kotlin Android (Kotlin) theme={"theme":{"light":"github-light","dark":"dracula"}}
  import com.spotify.confidence.ConfidenceFactory
  import com.spotify.confidence.ConfidenceValue
  import com.spotify.confidence.LoggingLevel

  // Create the Confidence SDK with context that is relevant for your flag, like the user ID.
  val confidence = ConfidenceFactory.create(
    context = app.applicationContext,
    clientSecret = "<CLIENT_SECRET>",
    initialContext = mapOf(
        "user_id" to ConfidenceValue.String("user-test-id"),
        "plan" to ConfidenceValue.String("premium"))
    ),
    loggingLevel = LoggingLevel.DEBUG
  )

  runBlocking { // note that this would potentially block a UI thread, so adjust scope as needed
    confidence.fetchAndActivate()
  }
  ```
</CodeGroup>

### Access the Flag

You can access the flag and its values.

<CodeGroup>
  ```javascript Javascript (Web) theme={"theme":{"light":"github-light","dark":"dracula"}}
  // value is { size: <something>, color: <something>}
  const value = confidence.getFlag(
    'header-redesign',
    // default value:
    {
      size: 10,
      color: 'green',
    },
  );
  ```

  ```javascript Javascript (Server) theme={"theme":{"light":"github-light","dark":"dracula"}}
  const client = parent.withContext({
    user_id: 'user-test-id',
    plan: 'premium',
  });
  // value is { size: <something>, color: <something>}
  const value = await client.getFlag(
    'header-redesign',
    // default value:
    {
      size: 10,
      color: 'green',
    },
  );
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"dracula"}}
  client = confidence.with_context({
    "user_id": "user-test-id",
    "plan": "premium"
  })

  # value is {'size': <something>, 'color': <something>}

  value = client.resolve_object_details(
  flag_key='header-redesign',
  default_value={'size': 10, 'color': 'green'}
  )

  ```

  ```java Java theme={"theme":{"light":"github-light","dark":"dracula"}}
  final Confidence client =
    confidence.withContext(ImmutableMap.of(
      "user_id", ConfidenceValue.of("user-test-id"),
      "plan", ConfidenceValue.of("premium")
    ));
  // value is { size: <something>, color: <something>}
  Struct value = client.getValue(
    "header-redesign",
    new Struct(Map.of(
      "size", ConfidenceValue.of(10),
      "color", ConfidenceValue.of("green")
    )));
  ```

  ```go Go theme={"theme":{"light":"github-light","dark":"dracula"}}
  client := confidence.WithContext(map[string]interface{}{
    "user_id": "user-test-id",
    "plan": "premium",
  })
  defaultValue := map[string]interface{}{}
  flagValue := client.GetObjectValue(
    context.Background(),
    "header-redesign",
    defaultValue,
  )
  ```

  ```swift iOS (Swift) theme={"theme":{"light":"github-light","dark":"dracula"}}
  // value is { size: <something>, color: <something>}
  let value = confidence.getValue(
    key: "header-redesign",
    defaultValue: [
      "size": 10,
      "color": "green"
    ]
  )
  ```

  ```kotlin Android (Kotlin) theme={"theme":{"light":"github-light","dark":"dracula"}}
    // value is { size: <something>, color: <something>}
    val value = confidence.getValue(
    key = "header-redesign",
    default = mapOf(
     "size" to ConfidenceValue.Integer(10),
      "color" to ConfidenceValue.String("green")
    )
  )
  ```

  ```bash Curl theme={"theme":{"light":"github-light","dark":"dracula"}}
  curl -H "Content-type: application/json" \
       --data '{
          "evaluation_context": {
            "user_id": "user-test-id",
            "plan": "premium"
          },
          "flags": ["flags/header-redesign"],
          "client_secret": "<CLIENT_SECRET>"
       }' \
       "https://resolver.confidence.dev/v1/flags:resolve"
  ```
</CodeGroup>

The code snippets above set two fields in the context: the `user_id` and the `plan` this user is on,
in this case `premium`.
You can use the `plan` field in the context to create targeted rules. For example, with this
information in the evaluation context, an A/B test can include only users on the premium plan as
its target audience.

This video gives a quick overview how targeting and evaluation contexts work in 2 minutes and 10 seconds.

<YouTubeVideo src="https://www.youtube.com/embed/rU82f1nRoGo?si=RvdoEFyt1OTdcOqr" />

<Info>
  If you were to run the code above you would only get the default values for
  the flag. Nothing tells the client that it should return any other value. To
  do so, you need to create flag variants and a rule that returns a variant.
</Info>

## Force a Variant For a User

To try out a variant you can force it for a user with a specific
user ID. You do this by creating an override rule on the flag. Override rules
let you give an experience to a selected set of attribute values, such as a
list of user IDs. For example, you can add the identifiers of the people on
your team to let only you test the new experience at an early stage.

To create an override rule, follow these steps.

1. Click **+ Create rule** and select **Override**.
2. Select `new-style` as the variant.
3. Enter `user_id` as the attribute.
4. Type in `user-test-id` in the **Values** section and hit enter.
5. Click **Save**.
6. Enable the rule by clicking the switch in the top left corner of the rule.

If you re-run the code that fetches the flag value you now see that the flag
resolves to a value other than the default.

### Force all Variant For 50% of Employees

You can create an override rule with a targeting audience that includes a subset
of the users in that audience. For example, you can create an override rule that
targets 50% of the users in the `"plan": "employee"` audience. This way, provided
that all employees have their plan set to `employee`, you can test the new experience
on a subset of your colleagues.

On the flag page

1. Click **+ Create rule** and select **Rollout**
2. Select `new-style` as the variant
3. In the audience section, click **Add attribute criterion** and write `plan` as field name with type `string` and click **Add**
4. Set the inclusion rule to be `plan is employee`
5. Enter `user_id` as the randomization unit
6. Set the allocation to 50%
7. Click **Save**
8. Turn on the rule by clicking the switch in the top left corner of the rule

<Frame>
  <img src="https://mintcdn.com/spotify-89f50c35/30KNAI5WzZFwyWnx/portal/guides/confidence-flags/enable-rule.png?fit=max&auto=format&n=30KNAI5WzZFwyWnx&q=85&s=27fdbf16bb52b6c8e2889a42831c6710" alt="Turn on the rule" width="1554" height="402" data-path="portal/guides/confidence-flags/enable-rule.png" />
</Frame>

Since you now have two rules, the rules evaluate in the order of the list on the
flag page. If a user is eligible for the first rule, it returns a variant for the user.
If not, Confidence Flags evaluates if the user is eligible for the second rule. In
this case, since only the user with ID `user-test-id` is eligible for the
override rule, Confidence Flags evaluates eligibility for the second rule for everyone
else. The second rule, in turn, only targets users on the `employee` plan.

Change the priority of the rules by dragging the rule cards
into the desired order and clicking save.

## Resolve Tester

Use the Resolve tester to see if the rule you expect returns a variant.
In the Resolve tester, you give an evaluation context and see which rules match and which don't, together with the reasons why.

On the page of your flag, select **Test rules** at the top of the list of rules.
Click **Add evaluation context** and give the context you want to test to
resolve. If you for example have created a rule that overrides the user with ID
`user-test-id` to the `new-style` variant, you can test that the rule matches by
adding the `user_id` field with the value `user-test-id` to the evaluation
context. Click **Resolve** to confirm that the override rule succeeds and
returns the `new-style` variant.

Most of the SDKs also output log messages that redirect you to the resolve tester specifically for the
flag evaluation that the SDK performed.
The link has a message with the prefix:

> See resolves for \<flagName> in Confidence:

To share a specific test run with someone, copy the URL and send it as a link.
The link directs them to the Resolve tester with all context data preserved.
