Skip to content

Commit

Permalink
feat: added and configured growthbook
Browse files Browse the repository at this point in the history
  • Loading branch information
lazarkulasevic committed Mar 19, 2024
1 parent b96bc9f commit ca0aaec
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 36 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_GROWTHBOOK_API_HOST=https://cdn.growthbook.io
1 change: 1 addition & 0 deletions .env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_GROWTHBOOK_CLIENT_KEY=sdk-AA8040Wd3Gxkiii3
1 change: 1 addition & 0 deletions .env.production
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_GROWTHBOOK_CLIENT_KEY=sdk-3E2uA3K4WbpbUS8
34 changes: 34 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"preview": "vite preview"
},
"dependencies": {
"@growthbook/growthbook-react": "^0.25.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
10 changes: 5 additions & 5 deletions src/Feature.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import useFeature from "./UseFeature.hook"
import type { PropsWithChildren, FC } from "react"

type FeatureProps = {
flag: string
children: React.ReactNode | React.ReactNode[]
}
} & PropsWithChildren

const Feature = ({ flag, children }: FeatureProps) => {
const isFeatureEnabled = useFeature(flag)
return isFeatureEnabled ? <>{children}</> : null
const Feature: FC<FeatureProps> = ({ flag, children }: FeatureProps) => {
const { enabled } = useFeature(flag)
return enabled ? <>{children}</> : null
}

export default Feature
27 changes: 27 additions & 0 deletions src/GrowthbookProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useEffect } from "react"
import type { PropsWithChildren, FC } from "react"
import { GrowthBook, GrowthBookProvider } from "@growthbook/growthbook-react"

const growthbook = new GrowthBook({
apiHost: import.meta.env.VITE_GROWTHBOOK_API_HOST,
clientKey: import.meta.env.VITE_GROWTHBOOK_CLIENT_KEY,
enableDevMode: import.meta.env.DEV,
subscribeToChanges: true,
})

const GrowthbookProvider: FC<PropsWithChildren> = ({ children }) => {
useEffect(() => {
// Load features asynchronously when the app renders
growthbook.loadFeatures()

return () => {
growthbook.destroy()
}
}, [])

return (
<GrowthBookProvider growthbook={growthbook}>{children}</GrowthBookProvider>
)
}

export default GrowthbookProvider
7 changes: 5 additions & 2 deletions src/UseFeature.hook.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
const useFeature = (feature: string): boolean => {
return __FEATURES__[feature]?.enabled === true
import { useFeatureIsOn } from "@growthbook/growthbook-react"

const useFeature = (feature: string) => {
const enabled = useFeatureIsOn(feature)
return { enabled }
}

export default useFeature
17 changes: 10 additions & 7 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import React from "react"
import ReactDOM from "react-dom/client"
import GrowthbookProvider from "./GrowthbookProvider.tsx"
import App from "./App.tsx"
import "./index.css"

ReactDOM.createRoot(document.getElementById('root')!).render(
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
<GrowthbookProvider>
<App />
</GrowthbookProvider>
</React.StrictMode>
)
24 changes: 2 additions & 22 deletions vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,12 @@
import { defineConfig } from "vite"
import React from "@vitejs/plugin-react-swc"
import envConfig from "./env.json"

type Env = keyof typeof envConfig

const featuresListProd = Object.keys(envConfig.production.features)
const allEnvsMatchProdFeatures = Object.keys(envConfig).every((env) => {
const currentFeaturesList = Object.keys(envConfig[env as Env].features)
return (
JSON.stringify(currentFeaturesList) === JSON.stringify(featuresListProd)
)
})

// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
if (!allEnvsMatchProdFeatures) {
console.error("\x1b[31m", "Features don't match across all environments.")
process.exit(1)
}

return {
plugins: [React()],

// Hosted on Github Pages under url https://lazarkulasevic.github.io/vite-feature-flags/
base: mode === "production" ? "/vite-feature-flags/" : "/",

define: {
__FEATURES__: JSON.stringify(envConfig[mode as Env].features),
},
// Hosted on Github Pages under url https://lazarkulasevic.github.io/growthbook-feature-flags/
base: mode === "production" ? "/growthbook-feature-flags/" : "/",
}
})

0 comments on commit ca0aaec

Please sign in to comment.