Implementing Feature Flags with Next.js and App Router
Kyle Johnson
Posted on November 2, 2023
Introduction
In this article we will discuss how we can combine the power of Vercel and feature flags (Flagsmith - open source) to build and deploy a config controlled application from scratch in less than 15 minutes using Next.Js feature flags. Written with Abhishek Agarawalš!
Through this blog, we will learn:
- The importance of feature flags
- How to create a basic Next.js application with Vercel Approuter
- Setting up Vercel and push the project to Vercel
- Deploy the application
- Add feature flags to it
- See real time changes on the website as we update feature flags from Flagsmith console
Background
Vercel is developersā favourite platform to develop, preview and ship any application. It makes building complex applications easier and much more efficient.
Next.js is a popular open-source framework provided by Vercel and built on top of Node.js for building server-side rendered (SSR) React applications. Its core advantages include faster page loads, better SEO, and improved developer experience.
Feature flags offer the power of managing features in production out of the box. We chose to integrate with Flagsmith (https://github.com/Flagsmith/flagsmith). The set-up and integration is seamless and provides enormous power with just the click of a few buttons.
Understanding Feature Flagging and Its Importance
Feature flagging, also known as feature toggling or feature flipping, is a powerful software development technique that enables developers to deploy new features and changes to production in a controlled and gradual manner. Instead of releasing all changes at once, feature flags allow you to selectively enable or disable specific features for different segments of your user base.
But why is this approach so valuable? There are several reasons why feature flagging has become an essential part of modern software development:
- Reduced Deployment Risks: Feature flagging reduces the risks associated with deploying new features. By gradually rolling out changes to a small subset of users, developers can closely monitor the impact and performance of the new features before making them available to a broader audience. This helps catch potential issues early and allows for quick adjustments if needed.
- Continuous Delivery and Experimentation: With feature flagging, you can continuously deliver updates and experiment with new features without causing disruptions to the entire user base. This enables agile development practices and encourages a culture of experimentation, where developers can test hypotheses and gather real-world data to inform their decisions.
- Personalized User Experiences: By segmenting users based on various traits (e.g., profession, location, subscription type), you can provide personalized experiences tailored to different user groups. This allows you to deliver targeted content, A/B test different variations, and optimize user engagement.
- Hotfixes and Rollbacks: Feature flags provide a safety net for quick hotfixes and rollbacks. If a new feature causes unexpected issues or receives negative feedback, you can easily turn it off with a flag, avoiding the need for a full redeployment.
Integrating Flagsmith with Next.js
In this guide, we've chosen Flagsmith as our feature flagging solution. Flagsmith is an open-source platform that offers a user-friendly interface for managing feature flags, A/B testing, and segment overrides. You can control feature behaviour without modifying code, making it a powerful tool for managing complex projects with multiple feature variations.
By integrating Flagsmith into our Next.js project deployed on Vercel, we gain the ability to perform phased rollouts, control feature visibility based on user segments, and dynamically change feature settings in real-time without redeploying the application.
Letās start building!
Flagsmith Account Setup
- If you do not have an account already, visit https://app.flagsmith.com/signup and create a new account. Flagsmith also offers simple sign in with Google or Github options.
- Create an organisation. For the purpose of this tutorial Iāll name it āFlagsmith <-> Vercelā. Feel free to pick your own.
- Create a project inside this organisation by clicking āCreate A Project''. Iāll just name it āmy-nextjs-projectā.
- Congrats! You have already completed the Flagsmith setup process. You should see a screen with instructions on how to create new features.
We will come back to this screen when we want to add Next.js feature flags to our application.
Github repo setup
Create a new repo on https://github.com/. I have named it āvercel-flagsmith-integrationā. Feel free to rename it.
Vercel account setup
- Visit https://vercel.com/signup and you can easily signup with your Github account
- Create a New project by Clicking Add New -> Project. You can simply visit https://vercel.com/new
- On the home page, all the Github repos associated with the account should be visible. Make sure the access to read repos is granted. The recently created project should also be visible in the list. Vercel automatically detects that it is a Next.js project.
- We will import this project once we have added some code
Now, letās start coding š
Create a starter Next.js project
We will be using the create-next-app
CLI tool to build us a starter project. Reference - https://nextjs.org/docs/api-reference/create-next-app . On the top of this, I have added a basic login page, so that we can take some user input and toggle behaviour based on that in the next steps.
We will be using the Vercel AppRouter paradigm for building our application.
Clone this repo to view the code https://github.com/abhishekag03/vercel-flagsmith-integration. Refer to the pull requests to understand the changes step by step. Specifically, this state of the repo describes the current expectation.
Letās deploy!
- Time to visit our Vercel dashboard again - https://vercel.com/new. Click on the āImportā button next to the repository where you just pushed.
- Hit the āDeployā button now
After the deployment has completed (typically it should not take more than a couple of minutes), click on the preview screen which will take you to the deployed website. The DNS in this case is https://vercel-flagsmith-integration.vercel.app/
You can visit the dashboard for your project (by clicking āContinue to Dashboardā in the above section) and view the domains and various other settings
Now, any change that we push to the āmainā branch of our repo will get deployed here in near real time!
Thatās how simple deploying applications with Vercel is!
Combining the power of Flagsmith with Vercel
We already saw how easy it is to set up and deploy a Next.js project. This is good for a basic project - however, in most cases we want more control towards the application behaviour.
For instance, imagine we want to add a new card to the below page. Currently it contains 4 cards - āDocsā, āLearnā, āTemplatesā and āDeployā. Adding a new card is trivial, but for large applications, such changes are always rolled out incrementally. They are rolled out either based on geography, type or percentage basis. Building this incremental rollout functionality can be tricky as it involves managing a lot of variables with real time updates.
Thatās where Flagsmith comes in. It offers a solution which allows you to manage all your Next.js feature flags, A/B testing and experimentation at one place with just the click of a button.
We will see how easy it is to rollout a feature to a certain segment of users with Flagsmith.
What we want is:
- On visiting the site, user should have an option to type their name and choose their Profession
- Upon submitting, based on the userās chosen profession, they should see the next screen.
- The screen behaviour based on professions should be controlled from the Flagsmith console.
- Change the list of professions dynamically on Flagsmith console and see realtime updates on our website
Integrating Flagsmith with Next.js Application
Add dependencies
We need to first add the flagsmith package. Run the below command: \
npm i flagsmith --save
Initialise the Flagsmith client
Now, we need to add code to initialise the flagsmith client.
TL;DR - Pull Request
Since we want the flagsmith features to be loaded and present in the state, we will create a provider file which handles loading the flag state and supplying it to our app pages. This allows us to use the FlagsmithProvider.
Thus, create a file named app/provider.tsx
. The content inside it should be as follows:
"use client";
import flagsmith from "flagsmith/isomorphic";
import { FlagsmithProvider } from "flagsmith/react";
import { IState } from "flagsmith/types";
import { ReactElement } from "react";
export default function Provider({
children,
flagsmithState,
}: {
children: React.ReactNode;
flagsmithState?: IState<string, string>;
}) {
return (
<FlagsmithProvider flagsmith={flagsmith} serverState={flagsmithState}>
{children as ReactElement}
</FlagsmithProvider>
);
}
The Flagsmith provider will allow all of its child components to access feature flags via the useFlags hook. In our example, we will fetch these flags from the server and pass them to the provider via the serverState property.
We will be importing this provider inside our app/layout.tsx file
. This is also the place where we call the init function for getting Flagsmith feature flag state.
Add the 2 imports as shown below:
import Provider from "./provider";
import flagsmith from "flagsmith/isomorphic";
The RootLayout
in the app/layout.tsx
file needs to updated as shown below:
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const flagsmithState = await flagsmith
.init({
// fetches flags on the server
environmentID: "heiEFz5x78igSLA8fGRgiP", // substitute your env ID
identity: "my_user_id", // specify the identity of the user to get their specific flags
})
.then(() => {
return flagsmith.getState();
});
return (
<html lang="en">
<body>
<Provider flagsmithState={flagsmithState}>
{children as ReactElement}
</Provider>
</body>
</html>
);
}
Remember to substitute your env specific environmentID in the layout.tsx file.
To get the environmentID, navigate back to the flagsmith website.
Click on āSettingsā for your environment, then click āKeysā.
Ensure that you are still able to successfully run the application by running:
yarn dev
Create a new card for the about page
As described in the agenda, we will add a new Card. This is the card that we intend rolling out in a phased manner based on user profession / segment.
TL;DR: Pull request
The below code can be added to the Page() function inside app/about/Page.tsx
file to get this new card.
<a
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
target="_blank"
rel="noopener noreferrer"
>
<h2 className={inter.className}>
Configure <span>-></span>
</h2>
<p className={inter.className}>
Configure your feature rollout with Flagsmith
</p>
</a>
Once this code is merged and deployed, this change will be visible to all the users who visit our website.
However, thatās not what we want. As a principal, new features are added incrementally. What if the Configure link was broken? What if there was an issue in the flow inside the configure? What if userās have started hating the Configure card and we want to remove it?
What if I told you all this control is possible with just a single click?
Letās add a phased rollout mechanism, so that only users with the profession āFreelancerā are shown this card first.
For this, we need to add a new feature on the Flagsmith dashboard.
Creating a Feature
Click on āCreate Your First Featureā option below:
Iām naming the feature āconfigure_card_controllerā since it controls the card named āConfigureā
Create Segment override
Letās edit this feature and create a Segment override. A segment override essentially allows you to configure the feature flag behaviour based on traits of the user. We will use the trait as āprofessionā in our example.
Click on the feature and navigate to the āSegment Overridesā tab. Click on āCreate Feature-Specific Segmentā
Adding an override for users with profession = freelancer
.
Segments can also be created globally for the project but in this case we just wanted the segment override for this one feature.
Segment overrides let you specify the enabled state and remote configuration of the feature. You can add as many segment overrides to a feature as you want, the priority of the overrides are dictated by their order.
Now that the segment override is added, Turn it on and save the override. Note that by default the feature is turned off, and only for this segment we have turned it on.
Control card with Flagsmith
TL;DR - Refer to this Pull request for the code changes - https://github.com/abhishekag03/vercel-flagsmith-integration/pull/11
Add the below import to app/about/page.tsx
import { useFlags } from "flagsmith/react";
Initialise the flag variable by telling it which feature flag key needs to be read
// only causes re-render if specified flag values change
const flags = useFlags(["configure_card_controller"]);
Now, wrap the newly added card (āConfigureā card) inside a condition, which checks for this flag.
The way we read the value of our flag is:
flags.configure_card_controller.enabled
To conditionally view the configure card, we will just enclose that card markup inside the following:
{flags.configure_card_controller.enabled &&
(
<a
... // the card segment code
</a>
)}
In order to get the appropriate screen when the user reaches this screen, we need to make sure that the flag trait gets set appropriately.
We will modify the handleOnSubmit
function to set the trait.
Add the below import and the line highlighted in green to the handleOnSubmit
function inside app/page.tsx
file.
The following code sets a Flagsmith trait
value based on user selection. Setting a trait is async, it will fetch the latest flags, considering any new segment overrides the user may have as a result of the trait.
import flagsmith from "flagsmith/isomorphic";
const handleOnSubmit = async(e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
await flagsmith.setTrait("profession", user.position); // setting the "profession" trait as the one selected by user
router.push("/about?name=" + user.name + "&position=" + user.position);
};
We need useRouter to get the information passed from the Login page.
We need to specify what flags and traits we are going to use in the code. As shown above, we are using the āconfigure_card_controllerā flag and āprofessionā trait. This makes the flags variable tightly coupled with these names, thereby reducing our chances of error while coding.
Testing and Experimentation
Deploy this code to Vercel and start testing.
Notice that when you choose the profession as Freelancer, you will see 5 cards. The āConfigureā card should be present.
On choosing any other profession, only 4 cards are visible:
You might be thinking that this could have been achieved with a trivial if/else condition - why do we need Flagsmith?
Flagsmith allows you to control these configurations on the fly without needing any code change or any redeployment.
For instance, if we see a good response from this new card - we would want to extend it to another Profession. To do that, we just need to go to the flagsmith UI and add the new profession name.
Letās try that - update the segment to also allow the ādesignerā profession to see this new card.
Edit the segment and add a condition for profession = ādesignerā.
On redeploying, you can see that both Freelancer and Designers are able to see this new card. The third profession (Frontend Developer) is still seeing the 4 cards.
Letās push this code and get it deployed to our main site.
The code is now live, and we are free to update the user segment and rollout as we need. You can test it running on https://vercel-flagsmith-integration.vercel.app/
Without any pull requests, code change, redeployment or testing, we were able to alter the behaviour of our website. This is a very powerful integration and can be used extensively for all small to large scale projects.
Conclusion
In conclusion, through this article, we demonstrated the practical application and significance of feature flags in a Next.js project hosted on Vercel. By integrating Flagsmith, we showcased how Next.js feature flags empower developers to reduce deployment risks, experiment safely, and deliver personalized user experiences. The ease of dynamic updates and segment overrides highlights the agility and control feature flags provide without code changes or redeployment. Through this hands-on approach, you can fine-tune feature rollouts and adapt your application based on user feedback, making feature flags a valuable tool for iterative and user-centric development. Embrace feature flags to unlock new possibilities and deliver exceptional user experiences in your software projects.
Hope you found this article useful and this integration helps you in building out applications!
Posted on November 2, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.