diff --git a/.github/workflows/beta.yml b/.github/workflows/beta.yml index 05ad2a0d3db..0046a6f128b 100644 --- a/.github/workflows/beta.yml +++ b/.github/workflows/beta.yml @@ -18,6 +18,7 @@ env: DATADOG_APPLICATION_ID: ${{ secrets.DATADOG_APPLICATION_ID }} DATADOG_CLIENT_TOKEN: ${{ secrets.DATADOG_CLIENT_TOKEN }} GATSBY_MAP_API_KEY: ${{ secrets.GATSBY_MAP_API_KEY }} + GATSBY_GROWTHBOOK_CLIENT_KEY: ${{ secrets.GATSBY_GROWTHBOOK_CLIENT_KEY }} jobs: release-beta: diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml index eeba734799b..e67cac68732 100644 --- a/.github/workflows/production.yml +++ b/.github/workflows/production.yml @@ -14,6 +14,7 @@ env: DATADOG_APPLICATION_ID: ${{ secrets.DATADOG_APPLICATION_ID }} DATADOG_CLIENT_TOKEN: ${{ secrets.DATADOG_CLIENT_TOKEN }} GATSBY_MAP_API_KEY: ${{ secrets.GATSBY_MAP_API_KEY }} + GATSBY_GROWTHBOOK_CLIENT_KEY: ${{ secrets.GATSBY_GROWTHBOOK_CLIENT_KEY }} jobs: release-production: diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index 7e1f0bbb6be..98d543c889b 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -18,6 +18,7 @@ env: DATADOG_APPLICATION_ID: ${{ secrets.DATADOG_APPLICATION_ID }} DATADOG_CLIENT_TOKEN: ${{ secrets.DATADOG_CLIENT_TOKEN }} GATSBY_MAP_API_KEY: ${{ secrets.GATSBY_MAP_API_KEY }} + GATSBY_GROWTHBOOK_CLIENT_KEY: ${{ secrets.GATSBY_GROWTHBOOK_CLIENT_KEY }} jobs: release-staging: diff --git a/package-lock.json b/package-lock.json index 2fe7927daf5..9e7e3dc4b43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,9 @@ "license": "Apache License 2.0", "dependencies": { "@artsy/fresnel": "^3.2.1", + "@deriv/analytics": "^1.0.2", "@deriv/deriv-api": "^1.0.11", + "@growthbook/growthbook-react": "^0.17.0", "@hookform/resolvers": "^3.0.1", "@livechat/customer-sdk": "^3.1.0", "@loadable/component": "^5.15.2", @@ -2816,6 +2818,18 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@deriv/analytics": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@deriv/analytics/-/analytics-1.0.2.tgz", + "integrity": "sha512-SwBZDeu/f4RGrdqOf3IGqKpoqJVxmAfLzAtMwO66xzyxGYn4oyYscJwGsjFPcAQ50euvaTe8YcqXn35PbdyDnQ==", + "dependencies": { + "rudder-sdk-js": "^2.35.0" + }, + "engines": { + "node": "18.x", + "npm": "9.x" + } + }, "node_modules/@deriv/api-types": { "version": "1.0.94", "resolved": "https://registry.npmjs.org/@deriv/api-types/-/api-types-1.0.94.tgz", @@ -4159,6 +4173,31 @@ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, + "node_modules/@growthbook/growthbook": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@growthbook/growthbook/-/growthbook-0.27.0.tgz", + "integrity": "sha512-gt/DWXfgyudY3gXAUjzKm9kMjVfCzfRc8d0nQQiXCP523ow23jThrmBzkRKCN+zxYVxUKcHjP9yjU9EKJqP4Fw==", + "dependencies": { + "dom-mutator": "^0.5.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@growthbook/growthbook-react": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@growthbook/growthbook-react/-/growthbook-react-0.17.0.tgz", + "integrity": "sha512-od+bSg3RD9AXfi/TWFDSzRaB6RuJLkUX5eFOZz8u8wL8yDbgd5RF9cwu4lQIF9/tyG1WLu4qipV+SM2v5s4BcQ==", + "dependencies": { + "@growthbook/growthbook": "^0.27.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16.8.0-0 || ^17.0.0-0 || ^18.0.0-0" + } + }, "node_modules/@grpc/grpc-js": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.7.3.tgz", @@ -22147,6 +22186,14 @@ "utila": "~0.4" } }, + "node_modules/dom-mutator": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/dom-mutator/-/dom-mutator-0.5.0.tgz", + "integrity": "sha512-bbeX8HWE8JGzraFgbVBX4ws2g3heZFuTtrleQBuN7huy+7n2n7etSuVnot3/1z3jdY2MiwuvoS4Ep1UT2rrGBw==", + "engines": { + "node": ">=10" + } + }, "node_modules/dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -44675,6 +44722,11 @@ "node": "6.* || >= 7.*" } }, + "node_modules/rudder-sdk-js": { + "version": "2.37.0", + "resolved": "https://registry.npmjs.org/rudder-sdk-js/-/rudder-sdk-js-2.37.0.tgz", + "integrity": "sha512-CyHoEJX9lHXZiQ1Mu5WqizkctFCpRagWio3mPhhqTDDMxDRdZow0p9UFXLOCCMpdkNmwcjakqk1nZWeeWwBqzQ==" + }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", diff --git a/package.json b/package.json index c00990f139d..80e18d06065 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,9 @@ "author": "Deriv", "dependencies": { "@artsy/fresnel": "^3.2.1", + "@deriv/analytics": "^1.0.2", "@deriv/deriv-api": "^1.0.11", + "@growthbook/growthbook-react": "^0.17.0", "@hookform/resolvers": "^3.0.1", "@livechat/customer-sdk": "^3.1.0", "@loadable/component": "^5.15.2", diff --git a/src/common/constants.ts b/src/common/constants.ts index 7f12e9959d4..61a1532f848 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -1,4 +1,6 @@ const MAP_API_KEY = process.env.GATSBY_MAP_API_KEY +const GATSBY_GROWTHBOOK_CLIENT_KEY = + process.env.GATSBY_GROWTHBOOK_CLIENT_KEY || 'sdk-0aHHaxKhwn0bP1HE' const isBrowser = () => typeof window !== 'undefined' export const deriv_com_url = 'deriv.com' @@ -122,6 +124,7 @@ export const dmt5_windows_url = 'https://download.mql5.com/cdn/web/deriv.limited/mt5/deriv5setup.exe' export const dp2p_google_play_url = 'https://play.google.com/store/apps/details?id=com.deriv.dp2p&hl=en&gl=US' +export const growthbook_client_key = GATSBY_GROWTHBOOK_CLIENT_KEY export const gtm_test_domain = 'deriv-com.binary.sx' export const livechat_client_id = '66aa088aad5a414484c1fd1fa8a5ace7' export const livechat_license_id = 12049137 diff --git a/src/features/pages/home/hero/content/index.tsx b/src/features/pages/home/hero/content/index.tsx index f60a7715fc0..c0cf67081c5 100644 --- a/src/features/pages/home/hero/content/index.tsx +++ b/src/features/pages/home/hero/content/index.tsx @@ -1,6 +1,7 @@ import React from 'react' import loadable from '@loadable/component' import pMinDelay from 'p-min-delay' +import { useFeatureValue } from '@growthbook/growthbook-react' import HeroCtaButton from './hero-cta.button' import { hero_typewriter, hero_content_title } from './hero-content.module.scss' import HeroHeaderItems from './hero-header.items' @@ -19,11 +20,20 @@ const HeroFeaturesCarousel = loadable(() => pMinDelay(import('./hero-features.ca }) const HomeHeroContent = () => { + const ebookStocksHeadingTest = useFeatureValue('homepage', 'control') + + const headings = { + control: '_t_Get the widest range of markets, trades and platforms_t_', + 'new-title': '_t_Get the widest range of markets, trades and platforms_t_', + } + + const heading = headings[ebookStocksHeadingTest] || headings.control + return ( - + diff --git a/src/pages/landing/ebooks/stocks.tsx b/src/pages/landing/ebooks/stocks.tsx index 26f173e5244..34c18db4db3 100644 --- a/src/pages/landing/ebooks/stocks.tsx +++ b/src/pages/landing/ebooks/stocks.tsx @@ -1,5 +1,6 @@ import React from 'react' import { graphql, useStaticQuery } from 'gatsby' +import { useFeatureValue } from '@growthbook/growthbook-react' import HeaderSection from './components/_header-section' import Introduction from './components/_introduction' import Topics from './components/_topics' @@ -29,6 +30,13 @@ const query = graphql` ` const StocksEbook = () => { + const ebookStocksHeadingTest = useFeatureValue('ebook-stocks-heading', 'control') + + const introMain = { + control: '_t_Learn to trade Stock derivatives the smart way_t_', + 'new-title': '_t_Learn to trade Stock derivatives the smart way_t_', + }[ebookStocksHeadingTest] + const data = useStaticQuery(query) return ( @@ -42,7 +50,7 @@ const StocksEbook = () => { imgWidth={557} imgHeight={703} ebook_utm_code="stock-ebook" - introMain="_t_Learn to trade Stock derivatives the smart way_t_" + introMain={introMain} authorDesc="_t_This e-book has been brought to you by a veteran online trader and New York Times bestselling author,_t_" authorName="_t_Vince Stanzione._t_" /> diff --git a/src/store/global-provider.tsx b/src/store/global-provider.tsx index 7c04740c43d..e7bb2623a79 100644 --- a/src/store/global-provider.tsx +++ b/src/store/global-provider.tsx @@ -3,20 +3,23 @@ import { BreakpointsProvider } from './breakpoints-context' import { PopupProvider } from './popup-context' import { RegionProvider } from './region-context' import { WebsiteStatusProvider } from './website-status-context' +import DerivGrowthBookProvider from './growthbook-context' import { MediaContextProvider } from 'themes/media' type GlobalProviderProps = { children: React.ReactNode } const GlobalProvider = ({ children }: GlobalProviderProps) => ( - - - - - {children} - - - - + + + + + + {children} + + + + + ) export default GlobalProvider diff --git a/src/store/growthbook-context.tsx b/src/store/growthbook-context.tsx new file mode 100644 index 00000000000..3bc86815dc7 --- /dev/null +++ b/src/store/growthbook-context.tsx @@ -0,0 +1,44 @@ +import React, { useEffect, useRef } from 'react' +import { GrowthBook, GrowthBookProvider } from '@growthbook/growthbook-react' +import { getClientInformation, getDomain, getLanguage } from 'common/utility' +import { growthbook_client_key } from 'common/constants' + +const DerivGrowthBookProvider = ({ children }: { children: React.ReactNode }) => { + const growthbook = useRef(); + useEffect(() => { + import('@deriv/analytics').then(({ RudderStack }) => { + const anonymousId = RudderStack.getAnonymousId() + growthbook.current = new GrowthBook({ + apiHost: 'https://cdn.growthbook.io', + clientKey: growthbook_client_key, + enableDevMode: true, + attributes: { + id: anonymousId, + }, + trackingCallback: (experiment, result) => { + RudderStack.track('experiment_viewed', { + experimentId: experiment.key, + variationId: result.variationId, + }) + }, + }) + growthbook.current.loadFeatures({ + autoRefresh: true, + }) + + const language = getLanguage() + const domain = getDomain() + const client_information = getClientInformation(domain) + + if (client_information) { + RudderStack.identifyEvent(client_information.loginid, { + language, + }) + } + }) + }, []); + + return {children} +} + +export default DerivGrowthBookProvider