Getting Started With React.js or React Router

Set up Flowgrid analytics on your React app in just a few easy steps. The guide below shows you how to integrate Flowgrid using React Router (React 18+)

Add the tracking script to app layout

Create your new website and add the following script tag preferably in the layout.jsx section:

  1. Within your project's components folder create InitialScript.jsx file.
  2. Open your project's app.jsx file then import the component above into your app router
  3. Add the Flowgrid tracking script tag inside the head section:
1import { useEffect } from 'react'; 2 3const InitialScript = () => { 4 useEffect(() => { 5 const script = document.createElement('script'); 6 script.src = 'https://core.flow-grid.xyz/flowgrid.js'; 7 script.async = true; 8 script.setAttribute('data-site', 'YOUR_WEBSITE_ID'); 9 script.setAttribute('data-api-key', 'YOUR_API_KEY'); 10 document.head.appendChild(script); 11 12 return () => { 13 // Optional cleanup 14 document.head.removeChild(script); 15 }; 16 }, []); 17 18 return null; 19}; 20 21export default InitialScript; 22

Use the npm SDK + drop-in helpers

Want typed, in-app tracking instead of the script tag? Install the SDK and lean on the built-in helpers so you never re-implement consent wiring or stable IDs by hand. They import directly from flowgrid-sdk.

1. Install

terminal
1npm install flowgrid-sdk 2# or: pnpm add flowgrid-sdk / yarn add flowgrid-sdk

2. Create a single setup file

Initialise FlowGrid once and re-export the helpers. setupConsent creates a consent manager andkeeps FlowGrid's consent gates in sync automatically.

src/lib/flowgrid.ts
1// src/lib/flowgrid.ts 2import { 3 FlowGrid, 4 setupConsent, 5 attachConsentBanner, 6 getOrCreateAnonId, 7 getOrCreateCartId, 8} from "flowgrid-sdk"; 9 10export const flowgrid = FlowGrid.init({ 11 // Vite env vars (use process.env.REACT_APP_* for Create React App). 12 webId: import.meta.env.VITE_FLOWGRID_WEB_ID, 13 apiKey: import.meta.env.VITE_FLOWGRID_API_KEY, 14 autoTrack: { performance: true, engagement: true, replay: true }, 15}); 16 17export const track = flowgrid.track.bind(flowgrid); 18 19// One call creates a consent manager AND keeps FlowGrid's consent gates in sync. 20export const getConsent = () => 21 setupConsent({ cookieName: "my_app_consent", cookieDays: 180, respectDNT: true }); 22 23// Re-export the drop-in helpers so the rest of your app imports from one place. 24export { attachConsentBanner, getOrCreateAnonId, getOrCreateCartId };

3. Cookie consent banner

Mount this component near your app root. No manual transport sync — getConsent() handled it.

src/components/CookieBanner.tsx
1// src/components/CookieBanner.tsx 2import { useEffect, useState } from "react"; 3import { getConsent } from "../lib/flowgrid"; 4 5export function CookieBanner() { 6 const [manager, setManager] = useState<ReturnType<typeof getConsent>>(); 7 const [visible, setVisible] = useState(false); 8 9 useEffect(() => { 10 const cm = getConsent(); // already pushes stored prefs into FlowGrid 11 setManager(cm); 12 if (!cm.hasConsented()) setVisible(true); 13 }, []); 14 15 if (!visible) return null; 16 17 return ( 18 <div id="cookie-banner" className="cookie-banner"> 19 <button onClick={() => { manager?.rejectNonEssential(); setVisible(false); }}> 20 Reject non-essential 21 </button> 22 <button onClick={() => { manager?.acceptAll(); setVisible(false); }}> 23 Accept all 24 </button> 25 </div> 26 ); 27}

Not using React for the banner?

Call attachConsentBanner() instead — it wires the#accept-btn /#reject-btn buttons inside any#cookie-banner element for you.

4. Track with stable IDs

getOrCreateAnonId() andgetOrCreateCartId() persist a stable visitor / cart id, so cart and checkout events line up automatically.

anywhere.ts
1import { track, flowgrid, getOrCreateAnonId, getOrCreateCartId } from "../lib/flowgrid"; 2 3// Product view — stable anonymous id, no boilerplate. 4track("product_view", { 5 productId: p.id, name: p.name, price: p.price, currency: "EUR", 6 userId: getOrCreateAnonId(), 7}); 8 9// Add to cart — every line in the session shares one cartId. 10flowgrid.cart.add( 11 { productId: p.id, name: p.name, price: p.price }, 12 1, 13 getOrCreateCartId(), 14);

5. Run an A/B experiment

exposureAuto() resolves the assigned variant and the visitor id for you, and localConversion() logs the win — no user-id threading required.

src/hooks/useExperiment.ts
1// src/hooks/useExperiment.ts 2import { useEffect, useState } from "react"; 3import { flowgrid } from "../lib/flowgrid"; 4 5export function useExperiment(id: string, variants: { id: string; weight: number }[]) { 6 const [variant, setVariant] = useState<string | null>(null); 7 8 useEffect(() => { 9 flowgrid.experiments.init([{ id, variants }]).then(() => { 10 setVariant(flowgrid.experiments.variant(id)); 11 flowgrid.experiments.exposureAuto(id); // resolves the variant + anon id for you 12 }); 13 }, [id]); 14 15 return { 16 variant, 17 convert: (metric: string, value = 1) => 18 flowgrid.experiments.localConversion(id, metric, value), 19 }; 20} 21 22// Usage in a component: 23// const { variant, convert } = useExperiment("hero_cta_copy", [ 24// { id: "control", weight: 50 }, 25// { id: "treatment", weight: 50 }, 26// ]); 27// <button onClick={() => convert("signup")}> 28// {variant === "treatment" ? "Start Free Trial" : "Book a Demo"} 29// </button>

Verify installation

After adding the script do the following to verify that the installation was successful:

  1. Open your website that you are now tracking in the browser.
  2. Go to your dashboard, click on your website and click the go to website's dashboard to see if the incoming traffic are being tracked.