Iāve been taking a deeper look at GitLabās full DevOps platform and their feature toggle offering caught my eye. This tool lets you configure and manage feature toggles directly from the GitLab UI. In the past I have looked at services like LaunchDarkly or Firebaseās A/B testing offering for feature toggles, I even tried my hand at building my own WordPress plugin back in 2018. But the thing that interests me most about GitLab offering is a combination of both configuration that doesnāt need a deployment to take effect, and also the proximity of the flagsā configuration to the development activities rather than another app.
What is a feature toggle?
At its most basic form a feature toggle is a boolean that tells an application to do one thing or another based on its value:
if(is_my_feature_enabled) {
doTheThing();
} else {
doTheOtherThing();
}
When you third party most providers this boolean variable becomes a function call to an SDK. For example this is how you check a feature flag with LaunchDarklyās JS SDK:
// Skipping the LaunchDarkly SDK setup for `LDClient`
const flagValue = myLaunchDarklyClient.variation('YOUR_FEATURE_KEY', false);
The above checks with the vendor to see if YOUR_FEATURE_KEY is enabled for the current user and
will resolve to either true or false when this line of code is executed. An important note
is that feature toggles are typically run-time and not build time. This allows you to
toggle behavior without redeploying an application, or enabling a feature for a small subset
of users at a time, what is known as an activation strategy, which we will look at once our
React app is connected.
Working with GitLab
Behind the scenes GitLab uses Unleash which is an open source feature management solution, but how to we use GitLabās feature toggles in a React app? There are three components we need to work on, these are:
- A GitLab project - Where weāre going to manage our feature flags
- A Proxy server - A secure way to communicate with our GitLab instance from the client
- A React app - Make changes to our React app to use these toggles
Our React app doesnāt communicate directly with the GitLab API, instead, we offer a dedicated proxy service secured by an authorisation secret to read the status of our feature flags. The React app then talks to the proxy that in tern communicates with our GitLab instance. Up first setting up our GitLab projectā¦
Setting up our GitLab Project Feature toggles in the UI
Weāre assuming you already have a GitLab repository/project (possibly home to your React app) that you want to use feature toggles with. If not you can register for a free account or checkout their pricing page. Once logged in to GitLab and while viewing your project (assuming you have the right permissions), under āDeploymentsā you should see an option titled Feature Flags.

If you have access you should be presented with a page that looks like this:

Our first stop is to click on the Configure button in the top right to open the Configure feature flags dialog:

We donāt need to do anything other than save both the API URL and Instance ID values as we
will need these in a moment when we configure our proxy. One last bit of preparation work will
be to create a GitLab Access token.
GitLab Access Token
This token will be used by the proxy service to communicate with your GitLab instance on your behalf. For this Iād recommend you create a project access token instead of using a personal one, to restrict it to the project youāre working with. Save your token somewhere safe we will need it in a moment.
The proxy server
Now we have our API Token (your Gitlab Access token), our Instance ID and our API URL weāre
ready to configure our proxy service. The proxy application sits between GitLab and our React
app (the client), this structure provides some security and performance benefits as it doesnāt
expose direct access to GitLab ensuring the internal feature toggle configuration isnāt exposed
to the world!
Unleash does offer a free tier āhostedā option instead of having to run your own proxy which you can find details about on their pricing page which also allows you to skip the need for Gitlab too if you want.
For this example weāre going to use the Docker image Unleash provides and run the proxy locally. We can use the following docker run command to pass the required environment variables to the container.
docker run -d \
-e UNLEASH_PROXY_SECRETS="RANDOM_STRING_9vZBzCd2jeqE7JY" \
-e UNLEASH_URL="https://gitlab.com/api/v4/feature_flags/..." \
-e UNLEASH_INSTANCE_ID="XXXXXXXXXXXXXXXXXXXX" \
-e UNLEASH_API_TOKEN=${GITLAB_PROJECT_ACCESS_TOKEN} \
-p 3000:3000 \
unleashorg/unleash-proxy
Wait where did these values come from? Letās recap what each of these variables is doing and where we got their values:
UNLEASH_PROXY_SECRETS- This is a randomly chosen secret is used in both the client and proxy, and is used to authorize calls to the proxy from the client app. This can be a comma separated list of secrets but in this example weāre passing a single stringRANDOM_STRING_9vZBzCd2jeqE7JY. Please use a sensible secret in production!UNLEASH_URL- This is our API URL from the GitLab configuration dialog.UNLEASH_INSTANCE_ID- This is theInstnce IDfrom the same configuration dialog.UNLEASH_API_TOKEN- This is our GitLab project access token (in this example I am passing in an exported variableGITLAB_PROJECT_ACCESS_TOKENto theDockerrun command.)
Only the UNLEASH_PROXY_SECRETS value is shared with the client app and you can find a more
detailed breakdown of the configuration details, their defaults and what theyāre used for on
the Unleash proxy configuration documentation.
Once the container is running you can cURL the service to verify its connected successfully:
curl -H "Content-Type: application/json" \
-H "Authorization: [One of your UNLEASH_PROXY_SECRETS values]" \
-X GET \
http://localhost:3000/proxy
If the proxy is working you can expect something like the following as a JSON response:
{
"toggles": []
}
Connect the client to the proxy
Now weāve got the proxy setup and have verified its connected, time for the React app. Weāre going to use Create React App and the official Unleash React client for this, which we can install by running the following in our (assumed to be already set up) React project:
npm install @unleash/proxy-client-react
With the client installed we can now adjust the app root to add
our context provider. With the Unleash
client we pass a config property, allowing it can connect to the proxy and ultimately out
GitLab instance. The following snippet shows how weāre doing this using environment variables.
Weāre using create-react-app in the following example it will pull our
values from our .env file in the projectās root directory.
import { FlagProvider } from '@unleash/proxy-client-react';
// Pull our config variables from our .env file
const {
REACT_APP_PROXY_URL,
REACT_APP_PROXY_CLIENT_KEY,
REACT_APP_PROXY_APP_NAME,
REACT_APP_PROXY_ENVIRONMENT
} = process.env;
// Set your config
const config = {
url: REACT_APP_PROXY_URL,
clientKey: REACT_APP_PROXY_CLIENT_KEY,
appName: REACT_APP_PROXY_APP_NAME,
environment: REACT_APP_PROXY_ENVIRONMENT,
refreshInterval: 300, // How often (in seconds) the client should poll thef proxy for updates.
};
// [...]
// In your root renderer:
root.render(
<React.StrictMode>
<FlagProvider config={config}>
<App />
</FlagProvider>
</React.StrictMode>
);
You can find out more about the configuration options in the @unleash/proxy-client-react
library in the
React SDK Initialization docs.
Now we have the provider configured we can start making use of the feature toggles inside our applicationās components. Here is a simple example that returns a paragraph tag with either the word āEnabledā or āDisabledā depending on the state of the toggle.
import { useFlag } from "@unleash/proxy-client-react";
export const ExampleComponent = () => {
const exampleFlag = useFlag(`example_flag_key`);
return <p>{ exampleFlag ? 'Enabled' : 'Disabled' }</p>
}
Running this you will see that example_flag_key is false. Which is correct as we have not
enabled a flag with that name, moreover we donāt even have a flag with that name. The useFlag
function will always return false if a flag is known and disabled, or unknown. To get this
component to show āEnabledā weāll need to create, and activate the toggle.
Adding a feature toggle
Letās add our flag and activate it to see this component go from āDisabledā to āEnabledā. Let us
head back to Gitlab and to you projectās āFeature Flagsā dashboard (via Deployments / Feature Flags ) use the button
in the top right labeled āNew Feature flagā, where you should be presented with a screen like this:

For the Name add example_flag_key or if you changed it add your flagās name. You will have to
ensure is a valid āslugā format, the name can contain lowercase letters, digits, ā_ā and ā-ā.
Once youāve added the name lets skip over the rest of the config and press āCreate feature flagā.

Once you create your flag you should be sent back to the list of flags with your new feature
toggle set to active by default. Now you can go back to your React app and once the
refreshInterval triggers a new fetch, the SDK should show your new flag as āEnabledā!
Activation strategies
Now we already know how to activate toggles for the app as a whole in the Gitlab admin. A more powerful feature of GitLab/Unleash comes in the form of activating features for specific users or enable it for a small group of users. Unleash call these āactivation strategiesā and offers four different ways to activate feature toggles these include:
Standard- Active for everyoneUserIDs- Active for users with a userId defined in the userIds listIPs- The remote address strategy activates a feature toggle for remote addresses defined in the IP list.Hostnames- The application hostname strategy activates a feature toggle for client instances with a hostName in the hostNames list.
Unleash does a much better job of detailing your options when it comes to activation strategies, Iād recommend checking out their Activation Strategies page.
An example using the UserId activation strategy
One of the activation strategies is using UserIDs. In the Gitlab UI we can target a specific
toggle to activate for specific values by configuring a User List and adding our newUserId
user ID to it. In the following example weāre updating the SDK to set the current userId to a
custom value which is included in our User List and once complete the toggle will activate.
import { useUnleashContext } from "@unleash/proxy-client-react";
import { ExampleComponent } from "../components/ExampleComponent.jsx"
export const UserActivation = () => {
const updateContext = useUnleashContext();
const setUserId = async (newUserIdValue) => {
console.log(`Set userId to ${newUserIdValue}`);
return updateContext({userId: newUserIdValue});
}
return (
<div>
<h1>Flag status for user: <ExampleComponent /></h1>
<button onClick={() => setUserId('newUserId')}>Set</button>
</div>
)
}
Be sure to check out the Activation Strategies page on the Unleash documentation along with GitLabās own docs for its feature toggle offering and the activation strategy that are supported out of the box.
With that weāve now set up a React app to use a Gitlab feature flags!