Prerequisites
- Free feature flagging account: http://optimizely.com/free-feature-flagging
- Optimizely CMS 12 website
Create a Full Stack project
Sign in to https://app.optimizely.com and create a new Full Stack project:
Add a feature flag
Go to Flags ➡ Create Flag and give it a descriptive name. Make note of the key and change it if necessary:
Switch the flag on
For now we only want our new feature to be enabled in development environments, so we switch it to On for Development while keeping it Off for Production:
Make note of your SDK keys
Go to Settings and make note of the SDK Key for each environment:
Prepare your website project
First we need to add the SDK. Since we're doing this for an Optimizely CMS website, we need the C# SDK. It is published as a NuGet package called Optimizely.SDK.
Next we add some code to the ConfigureServices method in our Startup class to initialize the SDK:
ProjectConfigManager fullStackProjectConfig =
new HttpProjectConfigManager.Builder()
.WithSdkKey("BzNk7YXpCd5NvVZm4n8Co") // Should be in environment-specific config
.WithPollingInterval(TimeSpan.FromMinutes(1)) // Refresh data file once per minute
.Build();
services.AddSingleton<IOptimizely>(new Optimizely(fullStackProjectConfig));
Implement feature flipping based on the flag
Next we add some code to conditionally (based on the feature flag) apply a browser theme color.
In this case we use Razor pages, so we add some logic to the page model:
public class SamplePageTypeModel : RazorPageModel<SamplePageType>
{
private readonly IOptimizely _fullStack;
public SamplePageTypeModel(IOptimizely fullStack)
{
_fullStack = fullStack;
}
public bool ApplyBrowserTheme { get; set; }
public void OnGet()
{
ApplyBrowserTheme = _fullStack.IsFeatureEnabled("apply_browser_theme_color", GetOrCreateUserId());
}
protected string GetOrCreateUserId()
{
const string cookieName = "fullStackUser";
// Return existing user ID, if any
if(Request.Cookies.TryGetValue(cookieName, out string? userId) && !string.IsNullOrWhiteSpace(userId))
{
return userId;
}
// Create new user ID
var newUserId = Guid.NewGuid().ToString();
Response.Cookies.Append(cookieName, newUserId);
return newUserId;
}
}
Finally we add some markup to be rendered only if the feature flag is On:
@if(Model.ApplyBrowserTheme)
{
<p>Theme is applied.</p>
<meta name="theme-color" content="#4285f4" />
}
else
{
<p>Theme is NOT applied.</p>
}
Testing the result
If we browse to our page, we see that our feature is indeed enabled:
We can now test switching the flag to Off (don't forget to hit Save at the bottom right):
When refreshing our page, we see the feature is no longer enabled:
Note: It may take up to a minute for the change to take effect since we configured Optimizely to only poll for changes once per minute.
What is the GetOrCreateUserId() method?
In the Razor page model we added a method called GetOrCreateUserId() to get a unique user ID which we pass on as an argument when invoking IsFeatureEnabled() to see if a flag is enabled.
The reason for this is to be able to divide users into different buckets (or audiences) for A/B tests, or to gradually roll out a feature, for example by enabling a flag for 25 % of the users.
To ensure a user isn't assigned to a different bucket/audience on every page load, it makes sense to assign a unique ID to each user.