DEV Community

Meks (they/them)
Meks (they/them)

Posted on

Add ConfigCat to Next.js App

I recently started helping my friend @jordan-t-romero with a NextJS and NodeJS project she is working on. This weekend we incorporated ConfigCat so that we can add feature flags to control what content is displayed in the different environments (local, staging, production, etc.)

Once we created an account and were logged in, we headed over to the React SDK Reference guide since Next.js is a framework for React.

Install Package

Since we use yarn instead of npm, we ran yard add configcat-react to add ConfigCat to our dependencies.

Import & Initialize a ConfigCatProvider with your SDK Key.

We wrapped our root component (_app.tsx in the Pages folder) with ConfigCatProvider to access ConfigCat features in child components.

import '../styles/globals.css'
import type { AppProps } from 'next/app'
import Layout from '../components/Layout/_layout'
import '../components/theme/styles.css'
import { ConfigCatProvider } from 'configcat-react'

export default function App({ Component, pageProps }: AppProps) {

  return (
    <ConfigCatProvider sdkKey="...your actual key">
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </ConfigCatProvider>
  )
}
Enter fullscreen mode Exit fullscreen mode

When you sign up with ConfigCat, if you go to the documentation, the sample code to paste in to add the provider will include your specific sdkKey.

Try it out

The first place we wanted to try it was in our NavBar. We eventually want to have a Login and Sign Up buttons, but they aren’t hooked up and we aren’t ready for real users on Production, so this was the ideal use case. In the ConfigCat app, we created a new feature to flag called signUpandLoginVisible and used the toggle to set it to on for testing purposes.

Screen shot of the modal pop-up of the ConfigCat site when you make a new feature flag. It has fields for a human readable name, a field for programs to use, an optional hint field to describe the feature, and toggles to initially set Test & Production environments on or off.

In components/Layout/Navbar.tsx we import useFeatureFlag and set a const for signUpandLoginVisible. The first arg for useFeatureFlag/2 is the name of the feature that is set in ConfigCat. The second arg is the default value to be used. Since the page loads slightly faster than the SDK Key can be read, it will use the default until it is connected with ConfigCat. Once we want to have these features shown, we will probably change the default to true. However it is so fast that we couldn’t tell the difference with our human eyes.

import NavComponent from './NavComponent'
import { useFeatureFlag } from 'configcat-react'

const Navbar = () => {
  const { value: signUpAndLoginVisible } = useFeatureFlag(
    'signUpAndLoginVisible',
    false,
  )

  return (
    <div>
      <NavComponent navText="Home" />
      <NavComponent navText="About" />
      <NavComponent navText="Contact" />
      {signUpAndLoginVisible ? <NavComponent navText="Sign Up" /> : null}
      {signUpAndLoginVisible ? <NavComponent navText="Login" /> : null}
    </div>
  )
}

export default Navbar
Enter fullscreen mode Exit fullscreen mode

A horizontal nav with buttons for Home, About, Contact, Sign Up, and Login.

And just like that we have a Sign Up and Login button! Then we can go in to ConfigCat, swith the toggle to off, wait a few seconds (usually about 60 seconds or more for us) for the change to take effect, and no more Sign Up or Login buttons!

ConfigCat signUpAndLoginVisible toggled off.

A horizontal nav with buttons for Home, About, and Contact.

Use an Environmental Variable

The final piece we wanted to implement was moving the SDK Key out of the app logic and into an Environment Variable. This is for a couple of reasons. You want to protect private keys like this and make sure they aren’t visible on places like GitHub where your code lives. Even if it is a private repository, extra protection is always better. The second is that we are using Vercel for our deployments and it gives us the ability to use different variables for our various environments.

We already have a .gitignore file in our home directory that includes our .env file:

# local env files
.env*.local
.env
Enter fullscreen mode Exit fullscreen mode

so in our .env file we can add where abc123 is your actual SDK Key:

NEXT_PUBLIC_CONFIGCAT_SDK_KEY=abc123
Enter fullscreen mode Exit fullscreen mode

Next.js comes with built in support for environmental variables. Because the variables in the .env file are by default only available server side (Node.js in our case), we need to add the NEXT_PUBLIC_ prefix to the variable name. This makes the environment variable accessible in the browser by allowing Next.js to read the value at build time and it is delivered to the client as part of the js bundle. We access the variable by calling process.env.[variable] within the code base. Our _app.tsx now looks like this:

...
import { ConfigCatProvider } from 'configcat-react'

export default function App({ Component, pageProps }: AppProps) {
  const CONFIGCAT_KEY = process.env.NEXT_PUBLIC_CONFIGCAT_SDK_KEY

  return (
    <ConfigCatProvider sdkKey={CONFIGCAT_KEY}>
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </ConfigCatProvider>
  )
}
Enter fullscreen mode Exit fullscreen mode

However, we now get have a typescript error:

Type 'string | undefined' is not assignable to type 'string'.
  Type 'undefined' is not assignable to type 'string'.ts(2322)
ConfigCatProvider.d.ts(7, 5): The expected type comes from property 'sdkKey' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<ConfigCatProvider> & Readonly<PropsWithChildren<ConfigCatProviderProps>>'
(property) sdkKey: string
Enter fullscreen mode Exit fullscreen mode

Because the SDK Key now comes from our .env file, when the app first boots up, the value is undefined until it becomes loaded. The loading process happens very fast so it shouldn’t have much of an effect on users, but we can add in a loading state until the value is available.

export default function App({ Component, pageProps }: AppProps) {
  const CONFIGCAT_KEY = process.env.NEXT_PUBLIC_CONFIGCAT_SDK_KEY

  if (!CONFIGCAT_KEY) {
    return <div>Loading...</div>
  }

  return (
    <ConfigCatProvider sdkKey={CONFIGCAT_KEY}>
        <Layout>
          <Component {...pageProps} />
        </Layout>
    </ConfigCatProvider>
  )
}
Enter fullscreen mode Exit fullscreen mode

And now we are all set with ConfigCat with a proper environment variable and are ready to fully use our feature flags.

Happy Coding!

Top comments (2)

Collapse
 
laliconfigcat profile image
Lajos Szoke

Hey there!

Awesome post! I'm really glad that you are trying ConfigCat and our React SDK.
I'm one of the devs behind the React SDK. I'd like to add 2 small suggestions for using the SDK, I hope you don't mind.

If you want to eliminate the default value "flickering" issue, I'd recommend you to use the second return parameter of the useFeatureFlag hook (loading). Something like this: configcat.com/docs/sdk-reference/r...

Also, you mentioned a 60 seconds wait interval after switching the feature flag. That is totally valid, the default polling method for the SDK is auto polling with a 60 seconds poll interval. If you'd like to, you can change the poll interval: configcat.com/docs/sdk-reference/r...

Happy feature flagging!

Collapse
 
mmcclure11 profile image
Meks (they/them)

Hey Lajos! Thanks for the insight and feedback. We will check out your suggestions. Much appreciated! And thank you for your work on React SDK!