Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update statsig template to require fewer env vars #1044

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
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/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ useCase:
- 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?demo-description=Reduce+CLS+and+improve+performance+from+client-loaded+experiments+at+the+edge+with+Statsig&demo-image=%2F%2Fimages.ctfassets.net%2Fe5382hct74si%2F3iWLIPxEQc7e5plRHDW5Nd%2Fdf781629a2e72f6ae5d05879787c4c79%2Fvercel_statsig.png&demo-title=Experimentation+with+Statsig&demo-url=https%3A%2F%2Fedge-ab-testing-statsig.vercel.app&envLink=https%3A%2F%2Fdocs.statsig.com%2Fguides%2Ffirst-feature&project-name=ab-testing-statsig&repository-name=ab-testing-statsig&repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fedge-middleware%2Fab-testing-statsig&products=%5B%7B%22integrationSlug%22%3A%22statsig%22%2C%22productSlug%22%3A%22statsig%22%2C%22type%22%3A%22integration%22%2C%22protocol%22%3A%22experimentation%22%7D%5D
demoUrl: https://edge-ab-testing-statsig.vercel.app
relatedTemplates:
- ab-testing-google-optimize
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?demo-description=Reduce+CLS+and+improve+performance+from+client-loaded+experiments+at+the+edge+with+Statsig&demo-image=%2F%2Fimages.ctfassets.net%2Fe5382hct74si%2F3iWLIPxEQc7e5plRHDW5Nd%2Fdf781629a2e72f6ae5d05879787c4c79%2Fvercel_statsig.png&demo-title=Experimentation+with+Statsig&demo-url=https%3A%2F%2Fedge-ab-testing-statsig.vercel.app&envLink=https%3A%2F%2Fdocs.statsig.com%2Fguides%2Ffirst-feature&project-name=ab-testing-statsig&repository-name=ab-testing-statsig&repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fedge-middleware%2Fab-testing-statsig&products=%5B%7B%22integrationSlug%22%3A%22statsig%22%2C%22productSlug%22%3A%22statsig%22%2C%22type%22%3A%22integration%22%2C%22protocol%22%3A%22experimentation%22%7D%5D)

### Clone and Deploy

Expand Down
27 changes: 16 additions & 11 deletions edge-middleware/ab-testing-statsig/lib/statsig-api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const STATSIG_URL = 'https://statsigapi.net'
const STATSIG_CONSOLE_API_KEY = process.env.STATSIG_CONSOLE_API_KEY!
const STATSIG_CONSOLE_API_KEY = process.env.STATSIG_CONSOLE_API_KEY ?? ''

/**
* Fetch wrapper for the Statsig API
Expand Down Expand Up @@ -44,17 +44,22 @@ async function statsig(

const api = {
async getBuckets(experiment: string) {
// https://docs.statsig.com/console-api/experiments#get-/experiments/-experiment_id-
const experimentConfig = await statsig(
`/console/v1/experiments/${experiment}`,
'GET',
{ apiKey: STATSIG_CONSOLE_API_KEY }
)
try {
// https://docs.statsig.com/console-api/experiments#get-/experiments/-experiment_id-
const experimentConfig = await statsig(
`/console/v1/experiments/${experiment}`,
'GET',
{ apiKey: STATSIG_CONSOLE_API_KEY }
)

return experimentConfig.data.groups.map(
(group: { parameterValues: { bucket: string } }) =>
group.parameterValues.bucket
)
return experimentConfig.data.groups.map(
(group: { parameterValues: { bucket: string } }) =>
group.parameterValues.bucket
)
} catch (e) {
console.error('Failed to fetch buckets from Statsig', e)
return []
}
},
}

Expand Down
16 changes: 11 additions & 5 deletions edge-middleware/ab-testing-statsig/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@ 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 dataAdapter = new EdgeConfigDataAdapter({
edgeConfigClient,
edgeConfigItemKey: process.env.EDGE_CONFIG_ITEM_KEY!,
})
let dataAdapter: EdgeConfigDataAdapter;

const missingEdgeConfigEnvVars = !process.env.EXPERIMENTATION_CONFIG || !process.env.EXPERIMENTATION_CONFIG_ITEM_KEY

if (!missingEdgeConfigEnvVars) {
const edgeConfigClient = createClient(process.env.EXPERIMENTATION_CONFIG)
dataAdapter = new EdgeConfigDataAdapter({
edgeConfigClient,
edgeConfigItemKey: process.env.EXPERIMENTATION_CONFIG_ITEM_KEY!,
})
}

export const config = {
matcher: '/',
Expand Down
61 changes: 46 additions & 15 deletions edge-middleware/ab-testing-statsig/pages/[bucket].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ import exampleScreenshot from '../public/example_experiment.png'

interface Props {
bucket: string
missingEdgeConfigEnvVars: boolean
missingConsoleApiEnvVars: boolean
}

export const getStaticProps: GetStaticProps<Props> = async ({ params }) => {
return {
props: {
bucket: params?.bucket as string,
missingEdgeConfigEnvVars: !process.env.EXPERIMENTATION_CONFIG || !process.env.EXPERIMENTATION_CONFIG_ITEM_KEY,
missingConsoleApiEnvVars: !process.env.STATSIG_CONSOLE_API_KEY,
},
}
}
Expand All @@ -35,12 +39,12 @@ export const getStaticPaths: GetStaticPaths<{ bucket: string }> = async () => {
.filter(Boolean)

return {
paths: groups.map((group) => ({ params: { bucket: group } })),
paths: groups.map((group) => ({ params: { bucket: group, missingEdgeConfigEnvVars: !process.env.EXPERIMENTATION_CONFIG || !process.env.EXPERIMENTATION_CONFIG_ITEM_KEY, missingConsoleApiEnvVars: !process.env.STATSIG_CONSOLE_API_KEY } })),
fallback: 'blocking',
}
}

function BucketPage({ bucket }: Props) {
function BucketPage({ bucket, missingEdgeConfigEnvVars, missingConsoleApiEnvVars }: Props) {
const { reload } = useRouter()

function resetBucket() {
Expand All @@ -52,23 +56,14 @@ function BucketPage({ bucket }: Props) {
return (
<Page className="flex flex-col gap-12">
<section className="flex flex-col gap-6">
<Text variant="h1">Performant experimentation with Statsig</Text>
<Text variant="h1">Experimentation with Statsig</Text>
<Text>
In this demo we use Statsig&apos;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
</Link>{' '}
to pull Statsig configurations from the edge. As long as you have a
experiment variants and show the resulting allocation. As long as you have a
bucket assigned you will always see the same result, otherwise you
will be assigned a bucket to mantain the odds specified in the
experiment.
</Text>
<Text>
Buckets are statically generated at build time in a{' '}
<Code>/[bucket]</Code> page so its fast to rewrite to them. Take a
look at the <Code>middleware.ts</Code> file to know more.
</Text>
<Text>
You can reset the bucket multiple times to get a different bucket
assigned. You can configure your experiments, see diagnostics and
Expand All @@ -90,8 +85,8 @@ function BucketPage({ bucket }: Props) {
<Text>
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.
</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>
Expand All @@ -101,6 +96,42 @@ function BucketPage({ bucket }: Props) {
/>
</section>

<section className="flex flex-col gap-6">
<Text variant="h1">Leveraging Edge Config For Performance</Text>
{
missingEdgeConfigEnvVars ?
<Text>
You can leverage the {' '}
<Link href="https://vercel.com/integrations/statsig" target="_blank">
edge config integration
</Link>{' '} to pull Statsig configurations from the edge to improve performance. Follow the README for more information.
</Text> :
<Text>
We leverage the{' '}
<Link href="https://vercel.com/integrations/statsig" target="_blank">
edge config integration
</Link>{' '}
to pull Statsig configurations from the edge.
</Text>
}

{
missingConsoleApiEnvVars ?
<Text>
Set the STATSIG_CONSOLE_API_KEY env variable to leverage static page
generation. The sample pre-renders pages at build time in a{' '}
<Code>/[bucket]</Code> page based on the experiment variants
so its fast to rewrite to them. Take a look at the
<Code>middleware.ts</Code> file to know more.
</Text> :
<Text>
Buckets are statically generated at build time in a{' '}
<Code>/[bucket]</Code> page so its fast to rewrite to them. Take a
look at the <Code>middleware.ts</Code> file to know more.
</Text>
}
</section>

<section className="flex flex-col gap-6">
<Text variant="h2">Using metrics in your experiments</Text>
<Text>
Expand Down