Next.js SDK Usage - App Router
Usage
Create the DevCycle Context and Export It
To use DevCycle on the server, you must create a context that can be shared across your server components. The context will hold the user data and configuration for the current request, and ensures subsequent calls to retrieve variables are scoped to that data.
In a shared file somewhere (for example, app/devcycle.ts
):
import { setupDevCycle } from '@devcycle/nextjs-sdk/server'
const getUserIdentity = async () => {
// pseudocode function representing some call you might make to
// your code to determine the current user
// You can use Next APIs such as `headers()` and `cookies()` here
const myUser = await determineUserIdentity(cookies())
return {
user_id: myUser.id
}
}
export const { getVariableValue, getClientContext } = setupDevCycle({
// Server SDK Key. This will be private and used to retrieve configuration data, so you MUST use the server SDK key.
serverSDKKey: process.env.DEVCYCLE_SERVER_SDK_KEY ?? '',
// Client SDK Key. This will be public and sent to the client, so you MUST use the client SDK key.
clientSDKKey: process.env.NEXT_PUBLIC_DEVCYCLE_CLIENT_SDK_KEY ?? '',
userGetter: getUserIdentity,
options: {}
})
Provide the context function to the DevCycleClientsideProvider as high as possible in your component tree.
import { DevCycleClientsideProvider } from '@devcycle/nextjs-sdk'
// import the getClientContext method from your shared DevCycle file
import { getClientContext } from './devcycle'
export default async function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<DevCycleClientsideProvider
context={getClientContext()}
>
{children}
</DevCycleClientsideProvider>
</body>
</html>
)
}
Note: You must use the correct type of SDK key for each key option provided here. The server key is used to retrieve privileged configuration information on the server, while the client key is required to instantiate the client SDK. Using the wrong key in either place risks leaking a server key to the client, or breaking server-side functionality.
The setupDevCycle method will:
- provide a
getVariableValue
method that encapsulates your configured SDK key, user getter and options - fetch your project's configuration from DevCycle when needed
- return a context to be passed to the client component provider that provides a clientside DevCycle SDK, and bootstraps it with the server's user and DevCycle configuration data.
It will also await the retrieval of the DevCycle configuration, thus blocking further rendering until the flag states have been retrieved and rendering can take place with the correct values.
Due to a bug in Next.js, realtime updates functionality is only available in Next.js 14.1 and above. If using a version below that, you must disable realtime updates to prevent clientside errors. To do so, pass the option in your initialization function:
export const { getVariableValue, getClientContext } = setupDevCycle({
serverSDKKey: process.env.DEVCYCLE_SERVER_SDK_KEY ?? '',
clientSDKKey: process.env.NEXT_PUBLIC_DEVCYCLE_CLIENT_SDK_KEY ?? '',
userGetter: getUserIdentity,
options: {
disableRealtimeUpdates: true,
}
})
Get a Variable Value
Server Component
import { getVariableValue } from './devcycle'
import * as React from 'react'
export const MyServerComponent = async function () {
const myVariable = await getVariableValue('myVariable', false)
return myVariable ? <NewComponent/> : <OldComponent/>
}
Note: it is recommended to use a module alias to access your DevCycle shared file from your server components. https://nextjs.org/docs/app/building-your-application/configuring/absolute-imports-and-module-aliases
Client Component
'use client'
import { useVariableValue } from '@devcycle/nextjs-sdk'
import * as React from 'react'
export const MyClientComponent = function () {
const myVariable = useVariableValue('myVariable', false)
return myVariable ? <NewComponent/> : <OldComponent/>
}