Skip to content
Merged
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
147 changes: 121 additions & 26 deletions packages/sdk/vercel/example-vercel/.gitignore
Original file line number Diff line number Diff line change
@@ -1,36 +1,131 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# dependencies
/node_modules
/.pnp
.pnp.js
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# testing
/coverage
# Runtime data
pids
*.pid
*.seed
*.pid.lock

# next.js
/.next/
/out/
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# production
/build
# Coverage directory used by tools like istanbul
coverage
*.lcov

# misc
.DS_Store
*.pem
# nyc test coverage
.nyc_output

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# local env files
.env*.local
# Bower dependency directory (https://bower.io/)
bower_components

# vercel
.vercel
# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# typescript
# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo
next-env.d.ts
.vscode

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp
.cache

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
.vercel
44 changes: 34 additions & 10 deletions packages/sdk/vercel/example-vercel/README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,54 @@
# Example test app for Vercel LaunchDarkly SDK

This is an example test app to showcase the usage of the Vercel LaunchDarkly
SDK. This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
SDK to evaluate a feature flag in a [Route Handler](https://nextjs.org/docs/app/building-your-application/routing/router-handlers) using [Vercel's edge runtime](https://nextjs.org/docs/app/building-your-application/routing/router-handlers#edge-and-nodejs-runtimes). This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

Most of the LaunchDarkly-related code can be found in [src/app/api/hello/route.ts](src/app/api/hello/route.ts).

## Prerequisites

A node environment of version 16 and yarn are required to develop in this repository.
You will also need the vercel cli installed and a Vercel account to setup
the test data required by this example. See the [Vercel docs](https://vercel.com/docs/storage/edge-config/get-started) on how to setup your edge config store.
You will also need the [Vercel CLI](https://vercel.com/docs/cli) installed and a Vercel account to setup
the test data required by this example. See the [Vercel docs](https://vercel.com/docs/storage/edge-config/get-started) on how to setup your Edge Config store.

## Setting up your LaunchDarkly environment

For simplicity, we recommend [creating a new LaunchDarkly project](https://docs.launchdarkly.com/home/organize/projects/?q=create+proj) for this example app. After creating a new project, create the following feature flags with Client-side SDK availability:

## Usage
- `test-flag` - (Boolean) - This flag is evaluated in [src/app/api/hello/route.ts](src/app/api/hello/route.ts).

1. Follow the [Vercel docs](https://vercel.com/docs/storage/edge-config/get-started) to insert [testData.json](https://github.com/launchdarkly/js-core/blob/main/packages/sdk/vercel/testData.json) to your edge config store.
After creating your project, you will need to configure the LaunchDarkly Vercel integration to push feature flag data to your Vercel Edge Config. Read the [Vercel integration documentation](https://docs.launchdarkly.com/integrations/vercel/) to set up the integration. Be sure to connect the **Test** environment from the project you created above.

2. After completing the guide above, you should have linked this example app to your Vercel project and created an `.env.development.local`.
## Setting up your development environment

1. Copy this directory in a new repository.
2. Create a new Vercel project based on the new repository.
3. [Add a new environment variable to your project](https://vercel.com/docs/concepts/projects/environment-variables) named `LD_CLIENT_SIDE_ID` and set it to the LaunchDarkly client-side ID for the **Test** environment in the project you created above.
4. Follow [Vercel's documentation](https://vercel.com/docs/storage/edge-config/get-started) to connect an Edge Config to your new project.
5. Run the following command to link your local codebase to your Vercel project:

```shell
vercel link
```

6. Run the following command to sync your projects environment variables in your development environment:

```shell
vercel env pull .env.development.local
```

3. At the root of the js-core repo:
7. After completing the guide above, you should have linked this example app to your Vercel project and created an `.env.development.local`.
8. Verify the contents of `.env.development.local` have values for the `LD_CLIENT_SIDE_ID` and `EDGE_CONFIG`.
9. Run the following command to install all dependencies:

```shell
yarn && yarn build
yarn
```

4. Then back in this example folder:
10. Run the following command to start your development environment:

```shell
yarn dev
```

5. Open [http://localhost:3000/api/hello](http://localhost:3000/api/hello).
11. Open [http://localhost:3000/api/hello](http://localhost:3000/api/hello).
5 changes: 5 additions & 0 deletions packages/sdk/vercel/example-vercel/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
12 changes: 6 additions & 6 deletions packages/sdk/vercel/example-vercel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
"packageManager": "yarn@3.4.1",
"scripts": {
"dev": "next dev",
"build": "tsc",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@launchdarkly/vercel-server-sdk": "0.3.0",
"@vercel/edge-config": "^0.1.8",
"next": "13.3.1",
"react": "18.2.0",
"@vercel/edge-config": "^0.2.1",
"next": "^13.4.4",
"react": "^18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@types/node": "18.16.2",
"@types/react": "18.2.0",
"@types/react-dom": "18.2.1",
"@types/react": "^18.2.7",
"@types/react-dom": "^18.2.4",
"autoprefixer": "10.4.14",
"postcss": "8.4.23",
"tailwindcss": "3.3.2",
Expand Down
46 changes: 25 additions & 21 deletions packages/sdk/vercel/example-vercel/src/app/api/hello/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,40 @@ import { NextResponse } from 'next/server';
import { createClient } from '@vercel/edge-config';
import { init as initLD } from '@launchdarkly/vercel-server-sdk';

export const config = {
runtime: 'edge',
};
export const runtime = 'edge';

export async function GET() {
const sdkKey = 'test-sdk-key';
const flagKey = 'testFlag1';
const clientSideID = process.env.LD_CLIENT_SIDE_ID;
if (!clientSideID) {
return NextResponse.json(
{
error: 'LD_CLIENT_SIDE_ID environment variable is missing.',
},
{ status: 500 }
);
}
const flagKey = 'test-flag';

// default fallthrough evaluates to true
const contextFallthrough = { kind: 'user', key: 'test-user-key-1' };

// matches email targeting rule evaluates to false
const contextEmailRule = { kind: 'user', key: 'test-user-key-1', email: 'test@gmail.com' };
// This is just a simple example context. You can also include request information such as headers and path or user ID
// if the request is authenticated.
const flagContext = { kind: 'user', key: 'test-user-key-1' };

const vercelClient = createClient(process.env.EDGE_CONFIG);

// start using ld
const client = initLD(sdkKey, vercelClient);
const client = initLD(clientSideID, vercelClient);
await client.waitForInitialization();
const fallthrough = await client.variation(flagKey, contextFallthrough, false);
const emailRule = await client.variation(flagKey, contextEmailRule, false);
const flagDetail = await client.variationDetail(flagKey, contextEmailRule, false);
const allFlags = await client.allFlagsState(contextEmailRule);

// Use .variation() to evaluate a single feature flag for a given context.
const testFlagVariation = await client.variation(flagKey, flagContext, false);

// allFlagsState() returns an object containing the variations served for all feature flags for a given context.
// This is useful for bootstrapping flags for use in the LaunchDarkly React SDK or JS client-side SDK.
const allFlags = await client.allFlagsState(flagContext);

return NextResponse.json({
flagKey: `${flagKey}`,
contextKey: `${contextFallthrough.key}`,
fallthrough,
emailRule,
emailRuleDetail: `${JSON.stringify(flagDetail)}`,
allFlags: `${JSON.stringify(allFlags)}`,
context: flagContext,
variationServed: testFlagVariation,
allFlags: allFlags.toJSON(),
});
}
3 changes: 1 addition & 2 deletions packages/sdk/vercel/example-vercel/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ export default function Home() {
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<div className="z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex">
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
Get started by editing&nbsp;
<code className="font-mono font-bold">src/app/page.tsx</code>
Get started by visiting&nbsp;<a href="/api/hello">/api/hello</a>
</p>
<div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none">
<a
Expand Down