Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions edge-middleware/ab-testing-statsig/.env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
EDGE_CONFIG=
EDGE_CONFIG_ITEM_KEY=
GLOBAL_CONFIG=
GLOBAL_CONFIG_ITEM_KEY=
STATSIG_SERVER_API_KEY=
STATSIG_CONSOLE_API_KEY=
NEXT_PUBLIC_STATSIG_CLIENT_KEY=
10 changes: 5 additions & 5 deletions edge-middleware/ab-testing-statsig/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ slug: ab-testing-statsig
description: Reduce CLS and improve performance from client-loaded experiments at the edge with Statsig
framework: Next.js
useCase:
- Edge Config
- Global Config
- Edge Middleware
- Documentation
css: Tailwind
deployUrl: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fedge-middleware%2Fab-testing-statsig&project-name=ab-testing-statsig&repository-name=ab-testing-statsig&integration-ids=oac_NAO87zzp3ADxj2ZUh3vikLip&env=STATSIG_SERVER_API_KEY,NEXT_PUBLIC_STATSIG_CLIENT_KEY,STATSIG_CONSOLE_API_KEY,EDGE_CONFIG,EDGE_CONFIG_ITEM_KEY&envDescription=Statsig%20API%20keys%20and%20Edge%20Config%20settings&envLink=https%3A%2F%2Fdocs.statsig.com%2Fguides%2Ffirst-feature
deployUrl: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fedge-middleware%2Fab-testing-statsig&project-name=ab-testing-statsig&repository-name=ab-testing-statsig&integration-ids=oac_NAO87zzp3ADxj2ZUh3vikLip&env=STATSIG_SERVER_API_KEY,NEXT_PUBLIC_STATSIG_CLIENT_KEY,STATSIG_CONSOLE_API_KEY,GLOBAL_CONFIG,GLOBAL_CONFIG_ITEM_KEY&envDescription=Statsig%20API%20keys%20and%20Global%20Config%20settings&envLink=https%3A%2F%2Fdocs.statsig.com%2Fguides%2Ffirst-feature
demoUrl: https://edge-ab-testing-statsig.vercel.app
relatedTemplates:
- ab-testing-google-optimize
Expand All @@ -17,7 +17,7 @@ relatedTemplates:

# Experimentation with Statsig

This example shows how to do experimentation using Statsig, leveraging Edge Config and Edge Middleware.
This example shows how to do experimentation using Statsig, leveraging Global Config and Edge Middleware.

## Demo

Expand All @@ -31,7 +31,7 @@ You can choose from one of the following two methods to use this repository:

Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=vercel-examples):

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fedge-middleware%2Fab-testing-statsig&project-name=ab-testing-statsig&repository-name=ab-testing-statsig&integration-ids=oac_NAO87zzp3ADxj2ZUh3vikLip&env=STATSIG_SERVER_API_KEY,NEXT_PUBLIC_STATSIG_CLIENT_KEY,STATSIG_CONSOLE_API_KEY,EDGE_CONFIG,EDGE_CONFIG_ITEM_KEY&envDescription=Statsig%20API%20keys%20and%20Edge%20Config%20settings&envLink=https%3A%2F%2Fdocs.statsig.com%2Fguides%2Ffirst-feature)
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fedge-middleware%2Fab-testing-statsig&project-name=ab-testing-statsig&repository-name=ab-testing-statsig&integration-ids=oac_NAO87zzp3ADxj2ZUh3vikLip&env=STATSIG_SERVER_API_KEY,NEXT_PUBLIC_STATSIG_CLIENT_KEY,STATSIG_CONSOLE_API_KEY,GLOBAL_CONFIG,GLOBAL_CONFIG_ITEM_KEY&envDescription=Statsig%20API%20keys%20and%20Global%20Config%20settings&envLink=https%3A%2F%2Fdocs.statsig.com%2Fguides%2Ffirst-feature)

### Clone and Deploy

Expand All @@ -53,7 +53,7 @@ cp .env.example .env.local
```

Install the [Statsig Vercel Integration](https://vercel.com/integrations/statsig) for your project.
Then fill in `.env.local` with the provided Edge Config Connection String and Edge Config Item Key.
Then fill in `.env.local` with the provided Global Config Connection String and Global Config Item Key.

Next, run Next.js in development mode:

Expand Down
12 changes: 6 additions & 6 deletions edge-middleware/ab-testing-statsig/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { NextRequest, NextResponse, NextFetchEvent } from 'next/server'
import Statsig from 'statsig-node-lite'
import { EdgeConfigDataAdapter } from 'statsig-node-vercel'
import { createClient } from '@vercel/edge-config'
import { createClient } from '@vercel/global-config'
import { EXPERIMENT, UID_COOKIE, GROUP_PARAM_FALLBACK } from './lib/constants'

// We'll use this to validate a random UUID
const IS_UUID = /^[0-9a-f-]+$/i

const edgeConfigClient = createClient(process.env.EDGE_CONFIG)
const edgeConfigClient = createClient(process.env.GLOBAL_CONFIG)
const dataAdapter = new EdgeConfigDataAdapter({
edgeConfigClient,
edgeConfigItemKey: process.env.EDGE_CONFIG_ITEM_KEY!,
edgeConfigItemKey: process.env.GLOBAL_CONFIG_ITEM_KEY!,
})

export const config = {
Expand Down Expand Up @@ -38,17 +38,17 @@ export async function middleware(req: NextRequest, event: NextFetchEvent) {
await Statsig.initialize(process.env.STATSIG_SERVER_API_KEY!, {
// 🚨 It's extremly important to set this, otherwise Statsig will attempt
// to fetch the ID List over the network, which is slow and would render
// using the Edge Config Adapter useless.
// using the Global Config Adapter useless.
//
// If you are not using the ID List feature, set this to "none".
//
// Otherwise consider setting it to "lazy" but be aware of the consequences
// that the ID List will not apply in most cases as it will only get fetched
// after the experiment ran
initStrategyForIDLists: 'none',
// This makes Statsig load experiments from Edge Config
// This makes Statsig load experiments from Global Config
dataAdapter,
// Disable any syncing to prevent network activity, as Edge Config will
// Disable any syncing to prevent network activity, as Global Config will
// return the latest values anyhow, and as ID Lists are disabled.
disableIdListsSync: true,
})
Expand Down
2 changes: 1 addition & 1 deletion edge-middleware/ab-testing-statsig/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"lint": "next lint"
},
"dependencies": {
"@vercel/edge-config": "^0.3.0",
"@vercel/global-config": "^1.5.0",
"@vercel/examples-ui": "^1.0.4",
"js-cookie": "^3.0.1",
"next": "^16.0.10",
Expand Down
20 changes: 10 additions & 10 deletions edge-middleware/ab-testing-statsig/pages/[bucket].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function BucketPage({ bucket }: Props) {
In this demo we use Statsig's Server SDK at the edge to pull
experiment variants and show the resulting allocation. We leverage the{' '}
<Link href="https://vercel.com/integrations/statsig" target="_blank">
edge config integration
global config integration
</Link>{' '}
to pull Statsig configurations from the edge. As long as you have a
bucket assigned you will always see the same result, otherwise you
Expand Down Expand Up @@ -88,17 +88,17 @@ function BucketPage({ bucket }: Props) {
Reset bucket
</Button>
<Text>
In order to set this demo up yourself, in the <Link href="https://console.statsig.com/" target="_blank">
In order to set this demo up yourself, in the{' '}
<Link href="https://console.statsig.com/" target="_blank">
Statsig console
</Link>, create a new experiment called &quot;statsig_example&quot;.
Create experiment groups, each with a &quot;bucket&quot; parameter.
Make sure to start the experiment, and from there this example will display the bucket that the user was assigned to.
See the screenshot below for an example experiment setup.
</Link>
, create a new experiment called &quot;statsig_example&quot;. Create
experiment groups, each with a &quot;bucket&quot; parameter. Make sure
to start the experiment, and from there this example will display the
bucket that the user was assigned to. See the screenshot below for an
example experiment setup.
</Text>
<Image
src={exampleScreenshot}
alt="Example Statsig Experiment Setup"
/>
<Image src={exampleScreenshot} alt="Example Statsig Experiment Setup" />
</section>

<section className="flex flex-col gap-6">
Expand Down
30 changes: 24 additions & 6 deletions edge-middleware/ab-testing-statsig/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion edge-middleware/feature-flag-apple-store/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
EDGE_CONFIG =
GLOBAL_CONFIG =
TEAM_ID_VERCEL=
AUTH_BEARER_TOKEN=
18 changes: 9 additions & 9 deletions edge-middleware/feature-flag-apple-store/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
---
name: Feature Flag Apple Store
slug: feature-flag-apple-store
description: This template uses Edge Config as fast storage to control whether a store is open or closed.
description: This template uses Global Config as fast storage to control whether a store is open or closed.
framework: Next.js
useCase:
- Edge Functions
- Edge Middleware
- Edge Config
- Global Config
css: Tailwind
deployUrl: 'https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fedge-middleware%2Ffeature-flag-apple-store&project-name=feature-flag-apple-store&repo-name=feature-flag-apple-store&env=EDGE_CONFIG&edge-config-stores=%7B%22EDGE_CONFIG%22%3A%7B%22featureFlagsAppleStore_storeClosed%22%3Atrue%7D%7D'
deployUrl: 'https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fedge-middleware%2Ffeature-flag-apple-store&project-name=feature-flag-apple-store&repo-name=feature-flag-apple-store&env=GLOBAL_CONFIG&global-config-stores=%7B%22GLOBAL_CONFIG%22%3A%7B%22featureFlagsAppleStore_storeClosed%22%3Atrue%7D%7D'
demoUrl: https://edge-functions-feature-flag-apple-store.vercel.app/
relatedTemplates:
- maintenance-page
Expand All @@ -18,7 +18,7 @@ relatedTemplates:

# Feature Flag Apple Store

This template uses Edge Config as fast storage to control whether the store is open or closed.
This template uses Global Config as fast storage to control whether the store is open or closed.

## Demo

Expand All @@ -32,7 +32,7 @@ You can choose from one of the following two methods to use this repository:

Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=vercel-examples):

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fedge-middleware%2Ffeature-flag-apple-store&project-name=feature-flag-apple-store&repo-name=feature-flag-apple-store&env=EDGE_CONFIG&edge-config-stores=%7B%22EDGE_CONFIG%22%3A%7B%22featureFlagsAppleStore_storeClosed%22%3Atrue%7D%7D)
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fedge-middleware%2Ffeature-flag-apple-store&project-name=feature-flag-apple-store&repo-name=feature-flag-apple-store&env=GLOBAL_CONFIG&global-config-stores=%7B%22GLOBAL_CONFIG%22%3A%7B%22featureFlagsAppleStore_storeClosed%22%3Atrue%7D%7D)

### Clone and Deploy

Expand All @@ -50,9 +50,9 @@ Copy the `.env.example` file in this directory to `.env.local` (which will be ig
cp .env.example .env.local
```

This example requires you to set up an Edge Config and store its connection string in the `EDGE_CONFIG` environment variable.
This example requires you to set up a Global Config and store its connection string in the `GLOBAL_CONFIG` environment variable.

Fill the Edge Config you create with this content:
Fill the Global Config you create with this content:

```json
{ "featureFlagsAppleStore_storeClosed": true }
Expand All @@ -68,7 +68,7 @@ Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&ut

## Opening / Closing the Store using the Dashboard

You can control whether the store is open or not by changing the value of `featureFlagsAppleStore_storeClosed` using the [Edge Config Dashboard](https://vercel.com/docs/concepts/edge-network/edge-config/edge-config-dashboard#manage-edge-configs).
You can control whether the store is open or not by changing the value of `featureFlagsAppleStore_storeClosed` using the [Global Config Dashboard](https://vercel.com/docs/concepts/edge-network/edge-config/edge-config-dashboard#manage-edge-configs).

## Opening / Closing the Store using API Routes

Expand All @@ -86,4 +86,4 @@ To close the store go to:
http://localhost:3000/api/store/close
```

Alternatively you can use the Edge Config UI in your Vercel dashboard to update the `featureFlagsAppleStore_storeClosed` value directly.
Alternatively you can use the Global Config UI in your Vercel dashboard to update the `featureFlagsAppleStore_storeClosed` value directly.
18 changes: 9 additions & 9 deletions edge-middleware/feature-flag-apple-store/lib/feature-flags.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { createClient, parseConnectionString } from '@vercel/edge-config'
import { createClient, parseConnectionString } from '@vercel/global-config'

interface FeatureFlags {
storeClosed: boolean
}

// We use prefixes to avoid mixing up the flags with other Edge Config values
// We use prefixes to avoid mixing up the flags with other Global Config values
const prefixKey = (key: string) => `featureFlagsAppleStore_${key}`

export async function get(key: keyof FeatureFlags) {
const prefixedKey = prefixKey(key)
const edgeConfig = createClient(process.env.EDGE_CONFIG)
const edgeConfig = createClient(process.env.GLOBAL_CONFIG)
const featureFlag = await edgeConfig.get<FeatureFlags>(prefixedKey)
return featureFlag
}
Expand All @@ -18,22 +18,22 @@ export async function set(key: keyof FeatureFlags, value: boolean) {
if (!process.env.AUTH_BEARER_TOKEN) {
throw new Error('Missing Environment Variable AUTH_BEARER_TOKEN')
}
if (!process.env.EDGE_CONFIG) {
throw new Error('Missing Environment Variable EDGE_CONFIG')
if (!process.env.GLOBAL_CONFIG) {
throw new Error('Missing Environment Variable GLOBAL_CONFIG')
}

const connectionString = parseConnectionString(process.env.EDGE_CONFIG!)
const connectionString = parseConnectionString(process.env.GLOBAL_CONFIG!)
if (!connectionString) {
throw new Error(
'Could not parse connection string stored in EDGE_CONFIG environment variable'
'Could not parse connection string stored in GLOBAL_CONFIG environment variable'
)
}

const edgeConfigId = connectionString.id
const globalConfigId = connectionString.id
const prefixedKey = prefixKey(key)

const response = await fetch(
`https://api.vercel.com/v1/edge-config/${edgeConfigId}/items?teamId=${process.env.TEAM_ID_VERCEL}`,
`https://api.vercel.com/v1/global-config/${globalConfigId}/items?teamId=${process.env.TEAM_ID_VERCEL}`,
{
method: 'PATCH',
headers: {
Expand Down
10 changes: 5 additions & 5 deletions edge-middleware/feature-flag-apple-store/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { NextRequest, NextResponse } from 'next/server'
import { get } from 'lib/feature-flags'
import { parseConnectionString } from '@vercel/edge-config'
import { parseConnectionString } from '@vercel/global-config'

export const config = {
matcher: '/',
}

export async function middleware(req: NextRequest) {
// for demo purposes, warn when there is no EDGE_CONFIG
// for demo purposes, warn when there is no GLOBAL_CONFIG
if (
!process.env.EDGE_CONFIG ||
!parseConnectionString(process.env.EDGE_CONFIG)
!process.env.GLOBAL_CONFIG ||
!parseConnectionString(process.env.GLOBAL_CONFIG)
) {
req.nextUrl.pathname = '/missing-edge-config'
req.nextUrl.pathname = '/missing-global-config'
return NextResponse.rewrite(req.nextUrl)
}

Expand Down
2 changes: 1 addition & 1 deletion edge-middleware/feature-flag-apple-store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"start": "next start"
},
"dependencies": {
"@vercel/edge-config": "0.1.0-canary.15",
"@vercel/global-config": "^1.5.0",
"next": "^16.0.10",
"react": "^19.2.1",
"react-dom": "^19.2.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default async function CloseStore() {
const result = await set('storeClosed', true)

if (!result) {
throw new Error(`Something went wrong when updating the Edge Config`)
throw new Error(`Something went wrong when updating the Global Config`)
}

return new Response(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default async function OpenStore() {
const result = await set('storeClosed', false)

if (!result) {
throw new Error(`Something went wrong when updating the Edge Config`)
throw new Error(`Something went wrong when updating the Global Config`)
}

return new Response(
Expand Down
Loading