{"id":24545047,"url":"https://github.com/kelvne/ab-react","last_synced_at":"2025-04-15T15:05:41.978Z","repository":{"id":257780801,"uuid":"860078722","full_name":"kelvne/ab-react","owner":"kelvne","description":"A/B testing component for React, works with SSR and CSR.","archived":false,"fork":false,"pushed_at":"2024-10-04T18:23:07.000Z","size":196,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-15T15:05:40.912Z","etag":null,"topics":["ab-testing","react","reactcomponent"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kelvne.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-09-19T19:28:56.000Z","updated_at":"2024-10-04T18:23:10.000Z","dependencies_parsed_at":null,"dependency_job_id":"6c053ed6-221f-4512-b3d9-625c9c7646f2","html_url":"https://github.com/kelvne/ab-react","commit_stats":null,"previous_names":["kelvne/ab-react"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelvne%2Fab-react","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelvne%2Fab-react/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelvne%2Fab-react/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelvne%2Fab-react/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kelvne","download_url":"https://codeload.github.com/kelvne/ab-react/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249094931,"owners_count":21211837,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ab-testing","react","reactcomponent"],"created_at":"2025-01-22T21:17:46.931Z","updated_at":"2025-04-15T15:05:41.972Z","avatar_url":"https://github.com/kelvne.png","language":"TypeScript","readme":"# ab-react\n\n![Jest coverage](./badges/coverage-jest%20coverage.svg)\n\nIf this component helped you or your team, please give it a GitHub 🌟!\n\n## Examples\n\n- Using SSR and CSR with [Next.js](#nextjs)\n- Plain CSR with [Vite.js](#vitejs)\n\n---\n\n## Installation\n\n```sh\nyarn add ab-react\n```\n\nor \n\n```sh\nnpm install -S ab-react\n```\n\n## Usage\n\n**This is mainly for AB testing, it will work with multiple children but try to stick with two.**\n\n### Normal use case\n\nIn the following example, three things can happen:\n\n1 - The ABReact component will randomize one of the children and store the value on a cookie, after that the user will always see the same version. \n\n2 - If a version is set on the cookie with the defined cookie name, that version will be rendered.\n\n3 - If a version is set on the cookie with the defined cookie name but the child doesn't exist null will be returned.\n\n**No matter what scenario happens, the trackVersion event will be called each time the component is rendered.**\n\n```tsx\nimport * as React from 'react';\nimport { useCallback } from 'react';\nimport ABReact from 'ab-react';\n\nexport default function MyComponent() {\n  const trackVersion = useCallback((version: number) =\u003e {\n    gtag('event', 'screen_view', {\n      'screen_name': 'MyComponent',\n      'version': version,\n    });\n  });\n\n  return (\n    \u003cABReact cookieName='cookie-name-to-store-version' event={trackVersion}\u003e\n      \u003cdiv key=\"version-1\"\u003eVersion 1\u003c/div\u003e\n      \u003cdiv key=\"version-2\"\u003eVersion 2\u003c/div\u003e\n    \u003c/ABReact\u003e\n  ) \n}\n```\n\n### If you are already using react-cookies and CookiesProvider\n\nIf you already has a top-level CookiesProvider mounted you can set a property so the ABReact won't mount the CookiesProvider internally:\n\n```tsx\nimport * as React from 'react';\nimport { useCallback } from 'react';\nimport ABReact from 'ab-react';\n\nexport default function MyComponent() {\n  return (\n    \u003cABReact cookieName='cookie-name' mountCookieProvider={false}\u003e\n      \u003cdiv key=\"version-1\"\u003eVersion 1\u003c/div\u003e\n      \u003cdiv key=\"version-2\"\u003eVersion 2\u003c/div\u003e\n    \u003c/ABReact\u003e\n  ) \n}\n```\n\n### Forcing a version\n\nIf you want to force a version to be rendered (to disable one or to maintain SSR consistency), you can set the property forceVersion:\n\n```tsx\nimport * as React from 'react';\nimport { useCallback } from 'react';\nimport ABReact from 'ab-react';\n\nexport default function MyComponent() {\n  return (\n    \u003cABReact cookieName='cookie-name' forceVersion={1}\u003e\n      \u003cdiv key=\"version-1\"\u003eVersion 1\u003c/div\u003e\n      \u003cdiv key=\"version-2\"\u003eVersion 2\u003c/div\u003e {/* This version will always be rendered */}\n    \u003c/ABReact\u003e\n  ) \n}\n```\n\n## Examples\n\n### Vite.js\n\n**Using only CSR (Client Side Rendering)**\n\n```tsx\nimport { useState, useCallback } from 'react';\nimport ABReact from 'ab-react';\n\nexport default function ABTesting() {\n  const [selectedState, setSelectedState] = useState\u003cstring\u003e('');\n\n  const eventExample = useCallback((version: number) =\u003e {\n    setSelectedState(version.toString());\n\n    /**\n     * Do any tracking here such as sending an event to Google Analytics\n     */\n  }, [setSelectedState]);\n\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003eNormal scenario for a pure client side rendering (CSR)\u003c/h1\u003e\n      \u003cABReact cookieName='cookie-1' event={eventExample}\u003e\n        \u003cdiv\u003e1\u003c/div\u003e\n        \u003cdiv\u003e2\u003c/div\u003e\n      \u003c/ABReact\u003e\n      \u003cp\u003eSelected version for cookie-1 (returned by the callback): { selectedState }\u003c/p\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n### Next.js\n\n**Using SSR (Server Side Rendering), CSR (Client Side Rendering) and AppRouter**\n\npage.tsx:\n```tsx\n/* file: page.tsx */\n\nimport { cookies } from 'next/headers';\n\nimport Components from './components';\n\nexport default function ABTestings() {\n  const v1 = Number(cookies().get('cookie-1')?.value);\n  const v2 = Number(cookies().get('cookie-2')?.value);\n\n  console.log(cookies().get('cookie-1'));\n\n  return (\n    \u003cdiv\u003e\n      \u003cComponents v1={Number.isNaN(v1) ? undefined : v1} v2={Number.isNaN(v2) ? undefined : v2} /\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\ncomponents.tsx:\n```tsx\n/* file: components.tsx */\n'use client';\nimport { useState, useCallback } from 'react';\nimport ABReact from 'ab-react';\n\nexport default function Components({ v1, v2 }: { v1?: number, v2?: number }) {\n  const [selectedState, setSelectedState] = useState\u003cstring\u003e('');\n\n  const eventExample = useCallback((version: number) =\u003e {\n    setSelectedState(version.toString());\n\n    /**\n     * Do any tracking here such as sending an event to Google Analytics\n     */\n  }, [setSelectedState]);\n\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003eNormal scenario, after SSR forces version from v1\u003c/h1\u003e\n      \u003cABReact cookieName='cookie-1' forceVersion={v1}\u003e\n        \u003cdiv\u003e1\u003c/div\u003e\n        \u003cdiv\u003e2\u003c/div\u003e\n      \u003c/ABReact\u003e\n\n      \u003ch1\u003eAnother scenario, after SSR forces version from v2 and runs an callback when the version is rendered\u003c/h1\u003e\n      \u003cABReact cookieName='cookie-2' event={eventExample} forceVersion={v2}\u003e\n        \u003cdiv\u003e1\u003c/div\u003e\n        \u003cdiv\u003e2\u003c/div\u003e\n      \u003c/ABReact\u003e\n      \u003cp\u003eSelected version for cookie-2 (returned by the callback): { selectedState }\u003c/p\u003e\n\n      \u003ch1\u003eForced version scenario, no internal choosing. Version hard coded.\u003c/h1\u003e\n      \u003cABReact cookieName='cookie-3' forceVersion={1}\u003e\n        \u003cdiv\u003e1\u003c/div\u003e\n        \u003cdiv\u003e2 forced\u003c/div\u003e\n      \u003c/ABReact\u003e\n    \u003c/div\u003e\n  );\n}\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkelvne%2Fab-react","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkelvne%2Fab-react","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkelvne%2Fab-react/lists"}