From 6424e1f1d90b47cb4a52b8282b043ca81a10ab4c Mon Sep 17 00:00:00 2001 From: Andres Alvarez Date: Mon, 22 Jun 2020 01:59:53 +0200 Subject: [PATCH] Add A/B Tests and Feature Flags example (#13629) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary This PR adds a basic example of how [Tesfy](https://tesfy.io/) could be integrated with Next.js. Tesfy is a project that I've working on during quarantine weekends, mainly to learn new stuff and provide **free** and **unlimited** A/B Tests and Feature Flags while keeping a good performance and the library [size](https://bundlephobia.com/result?p=react-tesfy@1.2.1) as small as possible. The configuration file could be set up using a [web application](https://app.tesfy.io/) (hosted in Vercel 🎉 ) or by your self. ## Implementation - Created `with-tesfy` folder - Added two pages `index.js` and `features.js` to show how experiments and features could be used - The only thing that must be persisted is the `userId`. Used a cookie to save it. - Uses `getServerSideProps` to fetch the configuration file and get/create the `userId`. ## Screenshots There are some screenshots from the web application. Where you can easily configure experiments and audiences per project. Teams and features will soon be added. ![Screenshot 2020-06-01 at 15 40 49](https://user-images.githubusercontent.com/6877967/83414811-60e7ce80-a41e-11ea-9e5c-887c66e80c65.png) ![Screenshot 2020-06-01 at 15 41 02](https://user-images.githubusercontent.com/6877967/83414823-66451900-a41e-11ea-885b-b58e78b042bb.png) ![Screenshot 2020-06-01 at 15 41 11](https://user-images.githubusercontent.com/6877967/83414828-6a713680-a41e-11ea-90a8-8d39a17f19a1.png) This is my first PR! sorry if I made something wrong 😞 . Any feedback is more than welcome. Also I want to thank you all for the awesome work with Next.js ❤️ --- examples/cms-agilitycms/README.md | 2 +- examples/cms-cosmic/README.md | 2 +- examples/cms-graphcms/README.md | 2 +- examples/with-tesfy/README.md | 50 ++++++++++++++++++++++ examples/with-tesfy/components/nav.js | 16 +++++++ examples/with-tesfy/package.json | 19 ++++++++ examples/with-tesfy/pages/_app.js | 26 +++++++++++ examples/with-tesfy/pages/features.js | 23 ++++++++++ examples/with-tesfy/pages/index.js | 43 +++++++++++++++++++ examples/with-tesfy/utils/getDatafile.js | 42 ++++++++++++++++++ examples/with-tesfy/utils/getTesfyProps.js | 13 ++++++ examples/with-tesfy/utils/getUserId.js | 31 ++++++++++++++ examples/with-tesfy/utils/index.js | 3 ++ 13 files changed, 269 insertions(+), 3 deletions(-) create mode 100644 examples/with-tesfy/README.md create mode 100644 examples/with-tesfy/components/nav.js create mode 100644 examples/with-tesfy/package.json create mode 100644 examples/with-tesfy/pages/_app.js create mode 100644 examples/with-tesfy/pages/features.js create mode 100644 examples/with-tesfy/pages/index.js create mode 100644 examples/with-tesfy/utils/getDatafile.js create mode 100644 examples/with-tesfy/utils/getTesfyProps.js create mode 100644 examples/with-tesfy/utils/getUserId.js create mode 100644 examples/with-tesfy/utils/index.js diff --git a/examples/cms-agilitycms/README.md b/examples/cms-agilitycms/README.md index eda23d2378bf9..146cf89317bd8 100644 --- a/examples/cms-agilitycms/README.md +++ b/examples/cms-agilitycms/README.md @@ -37,7 +37,7 @@ Once you have access to [the environment variables you'll need](#step-15-set-up- Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: ```bash -npm init next-app --example cms-agilitycms cms-agilitycms-app +npx create-next-app --example cms-agilitycms cms-agilitycms-app # or yarn create next-app --example cms-agilitycms cms-agilitycms-app ``` diff --git a/examples/cms-cosmic/README.md b/examples/cms-cosmic/README.md index ae2ee04a30072..1fc40b34730ac 100644 --- a/examples/cms-cosmic/README.md +++ b/examples/cms-cosmic/README.md @@ -32,7 +32,7 @@ Once you have access to [the environment variables you'll need](#step-3-set-up-e Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: ```bash -npm init next-app --example cms-cosmic cms-cosmic-app +npx create-next-app --example cms-cosmic cms-cosmic-app # or yarn create next-app --example cms-cosmic cms-cosmic-app ``` diff --git a/examples/cms-graphcms/README.md b/examples/cms-graphcms/README.md index b7a807ac946d6..f5f7b0b164473 100644 --- a/examples/cms-graphcms/README.md +++ b/examples/cms-graphcms/README.md @@ -37,7 +37,7 @@ Once you have access to [the environment variables you'll need](#step-3-set-up-e Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: ```bash -npm init next-app --example cms-graphcms cms-graphcms-app +npx create-next-app --example cms-graphcms cms-graphcms-app # or yarn create next-app --example cms-graphcms cms-graphcms-app ``` diff --git a/examples/with-tesfy/README.md b/examples/with-tesfy/README.md new file mode 100644 index 0000000000000..fd15316d99911 --- /dev/null +++ b/examples/with-tesfy/README.md @@ -0,0 +1,50 @@ +# Tesfy Example + +[Tesfy](https://tesfy.io/) allows you to create **unlimited** A/B Tests and Feature Flags for **free** using a [web app](https://app.tesfy.io/) or by your self. + +This example shows how to integrate [react-tesfy](https://github.com/andresz1/react-tesfy) in Next.js. + +To use Tesfy there are only two mandatory things needed. A `userId` and a configuration file known as `datafile`. In the `_app.js` you will notice that those are being get. + +The `userId` must uniquely identify a user even if not logged in, for that reason a [uuid](https://en.wikipedia.org/wiki/Universally_unique_identifier) is created and stored in a cookie so the next time a page is requested a new `userId` won't be created, instead the cookie one will be used. + +The `datafile` is just a `json` that defines the configuration of the experiments and features avaliable. It must be fetched from Tesfy CDN or from your own servers at least everytime a request is performed, later on this configuration could also be fetched if wanted (e.g. during page transitions). + +## Deploy your own + +Deploy the example using [Vercel](https://vercel.com): + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/vercel/next.js/tree/canary/examples/with-tesfy) + +## How to use + +### Using `create-next-app` + +Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: + +```bash +npx create-next-app --example with-tesfy with-tesfy-app +# or +yarn create next-app --example with-tesfy with-tesfy-app +``` + +### Download manually + +Download the example: + +```bash +curl https://codeload.github.com/vercel/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-tesfy +cd with-tesfy +``` + +Install it and run: + +```bash +npm install +npm run dev +# or +yarn +yarn dev +``` + +Deploy it to the cloud with [Vercel](https://vercel.com/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). diff --git a/examples/with-tesfy/components/nav.js b/examples/with-tesfy/components/nav.js new file mode 100644 index 0000000000000..fc45f88cfee3c --- /dev/null +++ b/examples/with-tesfy/components/nav.js @@ -0,0 +1,16 @@ +import Link from 'next/link' + +const Nav = () => { + return ( + + ) +} + +export default Nav diff --git a/examples/with-tesfy/package.json b/examples/with-tesfy/package.json new file mode 100644 index 0000000000000..f6ce8e634aae5 --- /dev/null +++ b/examples/with-tesfy/package.json @@ -0,0 +1,19 @@ +{ + "name": "with-tesfy", + "version": "1.0.0", + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "next": "latest", + "react": "^16.13.1", + "react-dom": "^16.13.1", + "react-tesfy": "latest", + "tesfy": "latest", + "cookie": "0.4.1", + "uuid": "8.1.0" + }, + "license": "ISC" +} diff --git a/examples/with-tesfy/pages/_app.js b/examples/with-tesfy/pages/_app.js new file mode 100644 index 0000000000000..9a98b07f52c21 --- /dev/null +++ b/examples/with-tesfy/pages/_app.js @@ -0,0 +1,26 @@ +import React from 'react' +import { TesfyProvider, createInstance } from 'react-tesfy' +import Nav from '../components/nav' + +const App = ({ Component, pageProps }) => { + const { datafile = {}, userId } = pageProps + const engine = createInstance({ + datafile, + userId, + }) + + return ( + +