Integration GuidesReact

React (Vite / CRA)

Add Rybbit analytics to your React app

A client-side React app built with Vite or Create React App has a single HTML entry file. Paste the snippet into its <head> and it loads on every route.

Get your tracking snippet

In your Rybbit dashboard, open Site Settings → Tracking Script and copy your snippet. It looks like this:

<script src="https://app.rybbit.io/api/script.js?siteId=YOUR_SITE_ID" defer></script>

YOUR_SITE_ID is the numeric ID of your site. If you self-host Rybbit, app.rybbit.io is the domain of your own instance.

Add the snippet to React

Find the HTML entry file for your tooling:

  • Vite: index.html at the project root.
  • Create React App: public/index.html.

Paste the snippet just before </head>:

index.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>My React App</title>
    <script src="https://app.rybbit.io/api/script.js?siteId=YOUR_SITE_ID" defer></script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

Placing it before </body> also works; <head> lets it start loading sooner. Route changes made by React Router and similar libraries are tracked automatically as pageviews.

Verify installation

Open your live site in a new tab and click through a few pages. Within a few seconds the pageviews appear in the Rybbit dashboard.

If nothing shows up:

  • View the page source and search for script.js?siteId= to confirm the snippet is on the page.
  • Open the browser Network tab and check that script.js returns 200 and that POST requests go to /api/track.
  • Disable ad blockers, or set up a proxy so the script loads from your own domain.
  • See the script troubleshooting guide for other common causes.

Track custom events

Call window.rybbit.event() from any component. Guard the call so a blocked or still-loading script does not throw.

src/components/LearnMoreButton.jsx
export default function LearnMoreButton() {
  const handleClick = () => {
    if (window.rybbit) {
      window.rybbit.event("button_click", { category: "CTA", label: "Learn More" });
    }
  };

  return <button onClick={handleClick}>Learn More</button>;
}

Troubleshooting

  • Pageviews missing after navigation: this is rare with React Router. If it happens, call window.rybbit.pageview() after each route change; test the default behaviour first.

Next steps

On this page