Proposed Pull Request Change

title titleSuffix description author ms.author ms.service ms.devlang ms.topic ms.date
Use variant feature flags in a Node.js application Azure App configuration In this tutorial, you learn how to use variant feature flags in a Node.js application zhiyuanliang-ms zhiyuanliang azure-app-configuration javascript tutorial 06/06/2025
📄 Document Links
GitHub View on GitHub Microsoft Learn View on Microsoft Learn
Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
+0 -0
+0 -0
--- title: 'Use variant feature flags in a Node.js application' titleSuffix: Azure App configuration description: In this tutorial, you learn how to use variant feature flags in a Node.js application #customerintent: As a user of Azure App Configuration, I want to learn how I can use variants and variant feature flags in my Node.js application. author: zhiyuanliang-ms ms.author: zhiyuanliang ms.service: azure-app-configuration ms.devlang: javascript ms.topic: tutorial ms.date: 06/06/2025 --- # Tutorial: Use variant feature flags in a Node.js application In this tutorial, you use a variant feature flag to manage experiences for different user segments in an example application, *Quote of the Day*. You utilize the variant feature flag created in [Use variant feature flags](./howto-variant-feature-flags.md). Before proceeding, ensure you create the variant feature flag named *Greeting* in your App Configuration store. ## Prerequisites * [LTS versions of Node.js](https://github.com/nodejs/release#release-schedule). * Follow the [Use variant feature flags](./howto-variant-feature-flags.md) tutorial and create the variant feature flag named *Greeting*. ## Create a Node.js application 1. Create a folder called `quote-of-the-day` and initialize the project. ```bash mkdir quote-of-the-day cd quote-of-the-day npm init -y ``` 1. Install the following packages. ```bash npm install @azure/app-configuration-provider npm install @microsoft/feature-management npm install express ``` 1. Create a new file named *server.js* and add the following code. ```js const express = require("express"); const server = express(); const appConfigEndpoint = process.env.AZURE_APPCONFIG_ENDPOINT; const { DefaultAzureCredential } = require("@azure/identity"); const { load } = require("@azure/app-configuration-provider"); const { FeatureManager, ConfigurationMapFeatureFlagProvider } = require("@microsoft/feature-management"); let appConfig; let featureManager; async function initializeConfig() { appConfig = await load(appConfigEndpoint, new DefaultAzureCredential(), { featureFlagOptions: { enabled: true, refresh: { enabled: true } } }); featureManager = new FeatureManager( new ConfigurationMapFeatureFlagProvider(appConfig)); } function startServer() { // Use a middleware to refresh the configuration before each request server.use((req, res, next) => { appConfig.refresh(); next(); }); server.use(express.json()); // Serve static index.html from the current folder server.use(express.static(".")); // This API returns the different greeting messages based on the segment the user belongs to. // It evaluates a variant feature flag based on user context. The greeting message is retrieved from the variant configuration. server.get("/api/getGreetingMessage", async (req, res) => { const { userId, groups } = req.query; const variant = await featureManager.getVariant("Greeting", { userId: userId, groups: groups ? groups.split(",") : [] }); res.status(200).send({ message: variant?.configuration }); }); server.post("/api/like", (req, res) => { const { UserId } = req.body; if (UserId === undefined) { return res.status(400).send({ error: "UserId is required" }); } // Here you would typically emit a 'like' event to compare variants. res.status(200).send(); }); const port = "8080"; server.listen(port, () => { console.log(`Server is running at http://localhost:${port}`); }); } // Initialize the configuration and start the server initializeConfig() .then(() => { startServer(); }) .catch((error) => { console.error("Failed to load configuration:", error); process.exit(1); }); ``` 1. Create a new file named *index.html* and add the following code: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Quote of the Day</title> <style> .heart-button { background-color: transparent; border: none; cursor: pointer; font-size: 24px; } .heart-button:hover { background-color: #F0F0F0; } </style> </head> <body> <div style="display: flex; flex-direction: column; min-height: 100vh; background-color: #f4f4f4;"> <header style="background-color: white; border-bottom: 1px solid #eaeaea; display: flex; justify-content: space-between; align-items: center; font-family: 'Arial', sans-serif; font-size: 16px;"> <div style="font-size: 1.25em; color: black;">QuoteOfTheDay</div> </header> <main style="display: flex; justify-content: center; align-items: center; flex-grow: 1;"> <div style="background-color: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); max-width: 700px; position: relative; text-align: left;"> <div id="quote-content"> <h2 id="greeting">Quote of the Day</h2> <blockquote style="font-size: 2em; font-style: italic; color: #4EC2F7; margin: 0 0 20px 0; line-height: 1.4;"> <p>"You cannot change what you are, only what you do."</p> <footer style="font-size: 0.55em; color: black; font-family: 'Arial', sans-serif; font-style: normal; font-weight: bold;">— Philip Pullman</footer> </blockquote> <div style="position: absolute; top: 10px; right: 10px; display: flex;"> <button class="heart-button" id="like-button"> <span id="heart-icon" style="color: #ccc">♥</span> </button> </div> </div> <div id="loading" style="display: none;"> <p>Loading</p> </div> </div> </main> </div> <script> // extract URL parameters to simulate user login document.addEventListener('DOMContentLoaded', function() { const urlParams = new URLSearchParams(window.location.search); const currentUser = urlParams.get('userId') || ''; let liked = false; const greetingElement = document.getElementById('greeting'); const heartIcon = document.getElementById('heart-icon'); const likeButton = document.getElementById('like-button'); const quoteContent = document.getElementById('quote-content'); const loadingElement = document.getElementById('loading'); async function init() { quoteContent.style.display = 'none'; loadingElement.style.display = 'block'; const response = await fetch(`/api/getGreetingMessage?userId=${currentUser}`, { method: "GET" }); const result = await response.json(); greetingElement.textContent = result.message || ""; quoteContent.style.display = 'block'; loadingElement.style.display = 'none'; } likeButton.addEventListener('click', async function() { if (!liked) { const response = await fetch("/api/like", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ UserId: currentUser }), }); } liked = !liked; heartIcon.style.color = liked ? 'red' : '#ccc'; }); init(); }); </script> </body> </html> ``` For simplicity, the example extracts the `userId` from URL query parameters (e.g., `?userId=UserA`) to simulate different user identities. ## Run the application 1. Set the environment variable named **AZURE_APPCONFIG_ENDPOINT** to the endpoint of your App Configuration store found under the *Overview* of your store in the Azure portal. If you use the Windows command prompt, run the following command and restart the command prompt to allow the change to take effect: ```cmd setx AZURE_APPCONFIG_ENDPOINT "<endpoint-of-your-app-configuration-store>" ``` If you use PowerShell, run the following command: ```powershell $Env:AZURE_APPCONFIG_ENDPOINT = "<endpoint-of-your-app-configuration-store>" ``` If you use macOS or Linux, run the following command: ```bash export AZURE_APPCONFIG_ENDPOINT='<endpoint-of-your-app-configuration-store>' ``` 1. Run the application. ```bash node server.js ``` 1. Open your browser and navigate to `localhost:8080`. You should see the default view of the app that doesn't have any greeting message. :::image type="content" source="media/howto-variant-feature-flags-javascript/default-variant.png" alt-text="Screenshot of the Quote of the day app, showing no greeting message for the user."::: 1. You can use `userId` query parameter in the url to specify the user ID. Visit `localhost:8080/?userId=UserA` and you see a long greeting message. :::image type="content" source="media/howto-variant-feature-flags-javascript/long-variant.png" alt-text="Screenshot of the Quote of the day app, showing long greeting message for the user."::: 1. Try different user IDs to see how the variant feature flag changes the greeting message for different segments of users. Visit `localhost:8080/?userId=UserB` and you see a shorter greeting message. :::image type="content" source="media/howto-variant-feature-flags-javascript/simple-variant.png" alt-text="Screenshot of the Quote of the day app, showing simple greeting message for the user."::: ## Next steps For the full feature rundown of the JavaScript feature management library, refer to the following document. > [!div class="nextstepaction"] > [JavaScript Feature Management](./feature-management-javascript-reference.md)
Success! Branch created successfully. Create Pull Request on GitHub
Error: