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(
// SDK Key. This will be public and sent to the client, so you MUST use the client SDK key.
process.env.NEXT_PUBLIC_DEVCYCLE_CLIENT_SDK_KEY ?? '',
// pass your method for getting the user identity
getUserIdentity,
// pass any options you want to use for the DevCycle SDK
{},
)
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 client SDK key of your project, not the server SDK key. The key is used across the server and the client and will be sent to the clientside to bootstrap the client SDK.
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:
const { getVariableValue, getClientContext } = setupDevCycle(
process.env.NEXT_PUBLIC_DEVCYCLE_CLIENT_SDK_KEY ?? '',
getUserIdentity,
{
// pass this option to disable realtime updates when using Next.js below 14.1
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/>
}
Tracking an Event
Client Component
'use client'
import * as React from 'react'
import { useTrack } from '@devcycle/nextjs-sdk'
export default MyComponent = function () {
const trackEvent = useTrack()
return (
<button onClick={() => trackEvent({type: 'myEvent'})}>
Track Event
</button>
)
}
Server Component
Currently, tracking events in server components is not supported due to limitations in Next.js. Please trigger any event tracking from client components.
Getting all Variables
Server Component
import { getAllVariables } from './devcycle'
import * as React from 'react'
export const MyServerComponent = async function () {
const allVariables = await getAllVariables()
return <div>JSON.stringify(allVariables)</div>
}
Client Component
import { useAllVariables } from '@devcycle/nextjs-sdk'
import * as React from 'react'
export const MyClientComponent = function () {
const allVariables = useAllVariables()
return <div>JSON.stringify(allVariables)</div>
}
Getting all Features
Server Component
import { getAllFeatures } from './devcycle'
import * as React from 'react'
export const MyServerComponent = async function () {
const allFeatures = await getAllFeatures()
return <div>JSON.stringify(allFeatures)</div>
}